summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/WebService/User.pm11
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-automative.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-creative.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-doc.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-finance.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-fxos-preload-app.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl1
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-legal.html.tmpl1
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl1
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-recruiting.html.tmpl1
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-user-engagement.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-webops-request.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/global/prod-comp-search.html.tmpl43
-rw-r--r--extensions/BMO/template/en/default/pages/group_membership.html.tmpl1
-rw-r--r--extensions/BMO/template/en/default/pages/triage_reports.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/pages/user_activity.html.tmpl2
-rw-r--r--extensions/BugModal/template/en/default/bug_modal/header.html.tmpl3
-rw-r--r--extensions/BugModal/web/bug_modal.css4
-rw-r--r--extensions/BugModal/web/bug_modal.js73
-rw-r--r--extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl2
-rw-r--r--extensions/MozProjectReview/template/en/default/bug/create/create-moz-project-review.html.tmpl2
-rw-r--r--extensions/ProdCompSearch/lib/WebService.pm11
-rw-r--r--extensions/ProdCompSearch/template/en/default/prodcompsearch/form.html.tmpl4
-rw-r--r--extensions/ProdCompSearch/web/js/prod_comp_search.js238
-rw-r--r--extensions/REMO/template/en/default/bug/create/create-mozreps.html.tmpl1
-rw-r--r--extensions/REMO/template/en/default/bug/create/create-remo-budget.html.tmpl2
-rw-r--r--extensions/Review/template/en/default/pages/review_history.html.tmpl1
-rw-r--r--extensions/Splinter/template/en/default/pages/splinter.html.tmpl1
-rw-r--r--extensions/UserProfile/template/en/default/pages/user_profile.html.tmpl1
-rw-r--r--js/comment-tagging.js55
-rw-r--r--js/field.js214
-rw-r--r--js/jquery/plugins/devbridgeAutocomplete/devbridgeAutocomplete-min.js8
-rw-r--r--js/jquery/plugins/devbridgeAutocomplete/license.txt21
-rw-r--r--skins/standard/global.css41
-rw-r--r--skins/standard/throbber.gifbin0 -> 723 bytes
-rw-r--r--template/en/default/account/prefs/prefs.html.tmpl1
-rw-r--r--template/en/default/admin/components/create.html.tmpl1
-rw-r--r--template/en/default/admin/components/edit.html.tmpl1
-rw-r--r--template/en/default/attachment/create.html.tmpl1
-rw-r--r--template/en/default/attachment/edit.html.tmpl1
-rw-r--r--template/en/default/bug/create/create.html.tmpl2
-rw-r--r--template/en/default/bug/edit.html.tmpl4
-rw-r--r--template/en/default/bug/field.html.tmpl25
-rw-r--r--template/en/default/bug/show-header.html.tmpl2
-rw-r--r--template/en/default/global/header.html.tmpl6
-rw-r--r--template/en/default/global/userselect.html.tmpl62
-rw-r--r--template/en/default/list/list.html.tmpl2
-rw-r--r--template/en/default/request/queue.html.tmpl1
-rw-r--r--template/en/default/search/field.html.tmpl21
-rw-r--r--template/en/default/search/form.html.tmpl18
-rw-r--r--template/en/default/search/search-advanced.html.tmpl2
-rw-r--r--template/en/default/search/search-create-series.html.tmpl2
-rw-r--r--template/en/default/search/search-report-graph.html.tmpl2
-rw-r--r--template/en/default/search/search-report-table.html.tmpl2
56 files changed, 454 insertions, 465 deletions
diff --git a/Bugzilla/WebService/User.pm b/Bugzilla/WebService/User.pm
index 8948a0195..8592d809c 100644
--- a/Bugzilla/WebService/User.pm
+++ b/Bugzilla/WebService/User.pm
@@ -27,7 +27,7 @@ use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Group;
use Bugzilla::User;
-use Bugzilla::Util qw(trim);
+use Bugzilla::Util qw(trim detaint_natural);
use Bugzilla::WebService::Util qw(filter filter_wants validate
translate params_to_objects);
use Bugzilla::Hook;
@@ -207,11 +207,14 @@ sub get {
userid => $obj->id});
}
}
-
+
# User Matching
my $limit;
- if ($params->{'maxusermatches'}) {
- $limit = $params->{'maxusermatches'} + 1;
+ if ($params->{limit}) {
+ detaint_natural($params->{limit})
+ || ThrowCodeError('param_must_be_numeric',
+ { function => 'User.match', param => 'limit' });
+ $limit = $limit ? min($params->{limit}, $limit) : $params->{limit};
}
my $exclude_disabled = $params->{'include_disabled'} ? 0 : 1;
foreach my $match_string (@{ $params->{'match'} || [] }) {
diff --git a/extensions/BMO/template/en/default/bug/create/create-automative.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-automative.html.tmpl
index 62d37e227..c19bed29b 100644
--- a/extensions/BMO/template/en/default/bug/create/create-automative.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-automative.html.tmpl
@@ -87,7 +87,7 @@ function validateAndSubmit() {
javascript = inline_javascript
javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
'js/field.js', 'js/util.js' ]
- yui = [ "autocomplete", "calendar", "selector" ]
+ yui = [ "calendar", "selector" ]
%]
[% USE Bugzilla %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-creative.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-creative.html.tmpl
index 1e18b71de..17ce19ccf 100644
--- a/extensions/BMO/template/en/default/bug/create/create-creative.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-creative.html.tmpl
@@ -116,7 +116,7 @@ function toggleTypeOther(element) {
javascript = inline_javascript
javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
'js/field.js', 'js/util.js' ]
- yui = [ "autocomplete", "calendar" ]
+ yui = [ "calendar" ]
%]
[% USE Bugzilla %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-doc.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-doc.html.tmpl
index 00ea21c0f..c7f883fb4 100644
--- a/extensions/BMO/template/en/default/bug/create/create-doc.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-doc.html.tmpl
@@ -40,7 +40,7 @@ function validateAndSubmit() {
javascript = inline_javascript
javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
'js/field.js', 'js/util.js', 'js/bug.js' ]
- yui = [ 'autocomplete', 'datatable', 'button' ]
+ yui = [ 'datatable', 'button' ]
%]
[% USE Bugzilla %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-finance.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-finance.html.tmpl
index d7734f042..8b2fd63da 100644
--- a/extensions/BMO/template/en/default/bug/create/create-finance.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-finance.html.tmpl
@@ -9,7 +9,7 @@
[% PROCESS global/variables.none.tmpl %]
[% inline_style = BLOCK %]
- #bug_form input[type=text], #bug_form input[type=file], #cc_autocomplete, #bug_form textarea {
+ #bug_form input[type=text], #bug_form input[type=file], #bug_form textarea {
width: 100%;
}
[% END %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-fxos-preload-app.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-fxos-preload-app.html.tmpl
index 105dc13ac..c51c5c91d 100644
--- a/extensions/BMO/template/en/default/bug/create/create-fxos-preload-app.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-fxos-preload-app.html.tmpl
@@ -87,7 +87,7 @@ function validateAndSubmit() {
javascript = inline_javascript
javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
'js/field.js', 'js/util.js' ]
- yui = [ "autocomplete", "calendar", "selector" ]
+ yui = [ "calendar", "selector" ]
%]
[% USE Bugzilla %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl
index ead28cd03..2a81b45bd 100644
--- a/extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl
@@ -84,7 +84,6 @@
generate_api_token = 1
javascript = inline_javascript
javascript_urls = [ 'js/field.js' ]
- yui = [ 'autocomplete' ]
%]
[% USE Bugzilla %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-legal.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-legal.html.tmpl
index 1b950475c..56ae2b7fc 100644
--- a/extensions/BMO/template/en/default/bug/create/create-legal.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-legal.html.tmpl
@@ -26,7 +26,6 @@
generate_api_token = 1
style_urls = [ 'skins/standard/attachment.css' ]
javascript_urls = [ 'js/attachment.js', 'js/field.js' ]
- yui = [ 'autocomplete' ]
%]
[% IF user.in_group("mozilla-employee-confidential")
diff --git a/extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl
index 078c82272..0fbce708b 100644
--- a/extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl
@@ -13,7 +13,6 @@
generate_api_token = 1
javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
'js/field.js' ]
- yui = [ 'autocomplete' ]
style = ".mandatory{color:red;font-size:80%;}"
%]
diff --git a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl
index 91921b43e..c62d8b99f 100644
--- a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl
@@ -274,7 +274,7 @@ function validate_form() {
javascript = inline_javascript
javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
'js/field.js', 'js/util.js' ]
- yui = [ "autocomplete", "calendar" ]
+ yui = [ "calendar" ]
%]
[% UNLESS user.in_group('pr-private') %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-recruiting.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-recruiting.html.tmpl
index 23b791d24..621bed533 100644
--- a/extensions/BMO/template/en/default/bug/create/create-recruiting.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-recruiting.html.tmpl
@@ -64,7 +64,6 @@ function jobDescToggle(what) {
javascript_urls = [ 'js/attachment.js', 'js/field.js' ]
style = inline_style
javascript = inline_javascript
- yui = [ 'autocomplete' ]
%]
[% IF user.in_group("mozilla-employee-confidential")
diff --git a/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl
index 8d2b14881..06e12c3d3 100644
--- a/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl
@@ -587,7 +587,7 @@ function showGear() {
javascript = inline_javascript
javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
'js/field.js', 'js/util.js' ]
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
%]
<h1>Mozilla Gear</h1>
diff --git a/extensions/BMO/template/en/default/bug/create/create-user-engagement.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-user-engagement.html.tmpl
index a6d5b8e1f..23ea0bb86 100644
--- a/extensions/BMO/template/en/default/bug/create/create-user-engagement.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-user-engagement.html.tmpl
@@ -81,7 +81,7 @@ function toggleGoalOther() {
javascript = inline_javascript
javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
'js/field.js', 'js/util.js' ]
- yui = [ "autocomplete", "calendar" ]
+ yui = [ "calendar" ]
%]
[% USE Bugzilla %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-webops-request.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-webops-request.html.tmpl
index 54a09c2de..03325469f 100644
--- a/extensions/BMO/template/en/default/bug/create/create-webops-request.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-webops-request.html.tmpl
@@ -71,7 +71,7 @@ function validateAndSubmit() {
javascript = inline_javascript
javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
'js/field.js', 'js/util.js' ]
- yui = [ "autocomplete", "selector" ]
+ yui = [ "selector" ]
%]
[% USE Bugzilla %]
diff --git a/extensions/BMO/template/en/default/global/prod-comp-search.html.tmpl b/extensions/BMO/template/en/default/global/prod-comp-search.html.tmpl
deleted file mode 100644
index 2f1d67bec..000000000
--- a/extensions/BMO/template/en/default/global/prod-comp-search.html.tmpl
+++ /dev/null
@@ -1,43 +0,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/.
- #
- # This Source Code Form is "Incompatible With Secondary Licenses", as
- # defined by the Mozilla Public License, v. 2.0.
- #%]
-
-<div id="prod_comp_search_main">
- <div id="prod_comp_search_autocomplete">
- <div id="prod_comp_search_label">
- Type to find product and component by name or description:
- <img id="prod_comp_throbber" src="extensions/BMO/web/images/throbber.gif"
- class="hidden" width="16" height="11">
- </div>
- <input id="prod_comp_search" type="text" size="60">
- <div id="prod_comp_search_autocomplete_container"></div>
- </div>
-</div>
-<script type="text/javascript">
- if(typeof(YAHOO.bugzilla.prodCompSearch) !== 'undefined'
- && YAHOO.bugzilla.prodCompSearch != null)
- {
- YAHOO.bugzilla.prodCompSearch.init(
- "prod_comp_search",
- "prod_comp_search_autocomplete_container",
- "[% format FILTER js %]",
- "[% cloned_bug_id FILTER js %]");
- [% IF target == "describecomponents.cgi" %]
- YAHOO.bugzilla.prodCompSearch.autoComplete.itemSelectEvent.subscribe(function (e, args) {
- var oData = args[2];
- var url = "describecomponents.cgi?product=" + encodeURIComponent(oData[0]) +
- "&component=" + encodeURIComponent(oData[1]) +
- "#" + encodeURIComponent(oData[1]);
- var format = YAHOO.bugzilla.prodCompSearch.format;
- if (format) {
- url += "&format=" + encodeURIComponent(format);
- }
- window.location.href = url;
- });
- [% END %]
- }
-</script>
diff --git a/extensions/BMO/template/en/default/pages/group_membership.html.tmpl b/extensions/BMO/template/en/default/pages/group_membership.html.tmpl
index 9218d44ed..a98354eac 100644
--- a/extensions/BMO/template/en/default/pages/group_membership.html.tmpl
+++ b/extensions/BMO/template/en/default/pages/group_membership.html.tmpl
@@ -9,7 +9,6 @@
[% PROCESS global/header.html.tmpl
title = "Group Membership Report"
generate_api_token = 1
- yui = [ 'autocomplete' ]
style_urls = [ "extensions/BMO/web/styles/reports.css" ]
javascript_urls = [ "js/field.js" ]
%]
diff --git a/extensions/BMO/template/en/default/pages/triage_reports.html.tmpl b/extensions/BMO/template/en/default/pages/triage_reports.html.tmpl
index a8cc85509..b0ca7e30d 100644
--- a/extensions/BMO/template/en/default/pages/triage_reports.html.tmpl
+++ b/extensions/BMO/template/en/default/pages/triage_reports.html.tmpl
@@ -41,7 +41,7 @@ var selected_components = [
[% INCLUDE global/header.html.tmpl
title = "Triage Reports"
generate_api_token = 1
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
javascript = js_data
javascript_urls = [ "js/util.js", "js/field.js", "js/productform.js",
"extensions/BMO/web/js/triage_reports.js" ]
diff --git a/extensions/BMO/template/en/default/pages/user_activity.html.tmpl b/extensions/BMO/template/en/default/pages/user_activity.html.tmpl
index 2ba463247..ad79b3c4d 100644
--- a/extensions/BMO/template/en/default/pages/user_activity.html.tmpl
+++ b/extensions/BMO/template/en/default/pages/user_activity.html.tmpl
@@ -15,7 +15,7 @@
[% INCLUDE global/header.html.tmpl
title = "User Activity Report" _ who_title
generate_api_token = 1
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
javascript_urls = [ "js/util.js", "js/field.js" ]
style_urls = [ "extensions/BMO/web/styles/reports.css" ]
diff --git a/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl
index 1fc00e82f..13ec7d567 100644
--- a/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl
+++ b/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl
@@ -37,9 +37,8 @@
jquery = [];
END;
- # right now we need yui for the user fields
+ # right now we need yui for tracking flags and needinfo extensions
no_yui = 0;
- yui = ['autocomplete'];
# add body classes for sec-groups, etc
FOREACH group IN bug.groups_in;
diff --git a/extensions/BugModal/web/bug_modal.css b/extensions/BugModal/web/bug_modal.css
index 3060d4fd6..e69bcaa2a 100644
--- a/extensions/BugModal/web/bug_modal.css
+++ b/extensions/BugModal/web/bug_modal.css
@@ -309,6 +309,10 @@ input[type="number"] {
float: right;
}
+#add-cc {
+ width: 100%;
+}
+
/* actions */
#top-actions {
diff --git a/extensions/BugModal/web/bug_modal.js b/extensions/BugModal/web/bug_modal.js
index b0b5f5317..66e214ad6 100644
--- a/extensions/BugModal/web/bug_modal.js
+++ b/extensions/BugModal/web/bug_modal.js
@@ -324,32 +324,24 @@ $(function() {
});
// keywords is a multi-value autocomplete
- // (this should probably be a simple jquery plugin)
keywords = data.keywords;
$('#keywords')
- .bind('keydown', function(event) {
- if (event.keyCode == $.ui.keyCode.TAB && $(this).autocomplete('instance').menu.active)
- {
- event.preventDefault();
- }
- })
- .blur(function() {
- $(this).val($(this).val().replace(/,\s*$/, ''));
- })
- .autocomplete({
- source: function(request, response) {
- response($.ui.autocomplete.filter(keywords, request.term.split(/,\s*/).pop()));
- },
- focus: function() {
- return false;
+ .devbridgeAutocomplete({
+ lookup: keywords,
+ tabDisabled: true,
+ delimiter: /,\s*/,
+ minChars: 0,
+ autoSelectFirst: true,
+ formatResult: function(suggestion, currentValue) {
+ // disable <b> wrapping of matched substring
+ return suggestion.value
+ .replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
},
- select: function(event, ui) {
- var terms = this.value.split(/,\s*/);
- terms.pop();
- terms.push(ui.item.value);
- terms.push('');
- this.value = terms.join(', ');
- return false;
+ onSelect: function() {
+ this.focus();
}
});
@@ -886,27 +878,20 @@ $(function() {
$('#product-search').show();
});
$('#pcs')
- .on('autocompleteselect', function(event, ui) {
- $('#product-search-error').hide();
- $('.pcs-form').hide();
- $('#product-search-cancel').hide();
- $('#product-search').show();
- if ($('#product').val() != ui.item.product) {
- $('#component').data('preselect', ui.item.component);
- $('#product').val(ui.item.product).change();
- }
- else {
- $('#component').val(ui.item.component);
- }
- $('#product').show();
- })
- .autocomplete('option', 'autoFocus', true)
- .keydown(function(event) {
- if (event.which == 13) {
- event.preventDefault();
- var enterKeyEvent = $.Event("keydown");
- enterKeyEvent.keyCode = $.ui.keyCode.ENTER;
- $('#pcs').trigger(enterKeyEvent);
+ .devbridgeAutocomplete('setOptions', {
+ onSelect: function(suggestion) {
+ $('#product-search-error').hide();
+ $('.pcs-form').hide();
+ $('#product-search-cancel').hide();
+ $('#product-search').show();
+ if ($('#product').val() != suggestion.data.product) {
+ $('#component').data('preselect', suggestion.data.component);
+ $('#product').val(suggestion.data.product).change();
+ }
+ else {
+ $('#component').val(suggestion.data.component);
+ }
+ $('#product').show();
}
});
$(document)
diff --git a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
index 47614a636..007ae5ce7 100644
--- a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
+++ b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
@@ -20,7 +20,7 @@
javascript_urls = js_urls
style_urls = [ 'extensions/GuidedBugEntry/web/style/guided.css',
'js/yui/assets/skins/sam/container.css' ]
- yui = [ 'history', 'datatable', 'container', 'autocomplete' ]
+ yui = [ 'history', 'datatable', 'container' ]
%]
<iframe id="yui-history-iframe" src="extensions/GuidedBugEntry/web/yui-history-iframe.txt"></iframe>
diff --git a/extensions/MozProjectReview/template/en/default/bug/create/create-moz-project-review.html.tmpl b/extensions/MozProjectReview/template/en/default/bug/create/create-moz-project-review.html.tmpl
index 593faa142..9c679dfa1 100644
--- a/extensions/MozProjectReview/template/en/default/bug/create/create-moz-project-review.html.tmpl
+++ b/extensions/MozProjectReview/template/en/default/bug/create/create-moz-project-review.html.tmpl
@@ -14,7 +14,7 @@
style_urls = [ 'extensions/MozProjectReview/web/style/moz_project_review.css' ]
javascript_urls = [ 'js/field.js', 'js/util.js',
'extensions/MozProjectReview/web/js/moz_project_review.js' ]
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
%]
<p>
diff --git a/extensions/ProdCompSearch/lib/WebService.pm b/extensions/ProdCompSearch/lib/WebService.pm
index a28b5d059..521d1588f 100644
--- a/extensions/ProdCompSearch/lib/WebService.pm
+++ b/extensions/ProdCompSearch/lib/WebService.pm
@@ -113,7 +113,7 @@ sub prod_comp_search {
unshift @order, "products.name != 'bugzilla.mozilla.org'";
}
- my $products = $dbh->selectall_arrayref("
+ my $components = $dbh->selectall_arrayref("
SELECT products.name AS product,
components.name AS component
FROM products
@@ -124,6 +124,15 @@ sub prod_comp_search {
ORDER BY " . join(", ", @order) . " $limit",
{ Slice => {} });
+ my $products = [];
+ my $current_product;
+ foreach my $component (@$components) {
+ if (!$current_product || $component->{product} ne $current_product) {
+ $current_product = $component->{product};
+ push @$products, { product => $current_product };
+ }
+ push @$products, $component;
+ }
return { products => $products };
}
diff --git a/extensions/ProdCompSearch/template/en/default/prodcompsearch/form.html.tmpl b/extensions/ProdCompSearch/template/en/default/prodcompsearch/form.html.tmpl
index 39919510c..c232f677d 100644
--- a/extensions/ProdCompSearch/template/en/default/prodcompsearch/form.html.tmpl
+++ b/extensions/ProdCompSearch/template/en/default/prodcompsearch/form.html.tmpl
@@ -35,10 +35,10 @@
<img id="[% id FILTER html %]-throbber"
src="extensions/ProdCompSearch/web/images/throbber.gif"
style="display:none" width="16" height="11">
- <span class="pcs-message" id="[% id FILTER html %]-no_components" style="display:none">
+ <span class="pcs-message" id="[% id FILTER html %]-no_results" style="display:none">
No components found
</span>
- <span class="pcs-message" id="[% id FILTER html %]-too_many_components" style="display:none">
+ <span class="pcs-message" id="[% id FILTER html %]-too_many_results" style="display:none">
Result limited to [% max_results FILTER html %] components
</span>
<span class="pcs-message" id="[% id FILTER html %]-error" style="display:none">
diff --git a/extensions/ProdCompSearch/web/js/prod_comp_search.js b/extensions/ProdCompSearch/web/js/prod_comp_search.js
index 2c9516967..69cc7cc0b 100644
--- a/extensions/ProdCompSearch/web/js/prod_comp_search.js
+++ b/extensions/ProdCompSearch/web/js/prod_comp_search.js
@@ -9,112 +9,142 @@
$(function() {
'use strict';
- $('.prod_comp_search').autocomplete({
- minLength: 3,
- delay: 500,
- source: function(request, response) {
- var el = this.element;
- $(document).trigger('pcs:search', [ el ]);
- var id = '#' + el.prop('id');
- var throbber = $('#' + $(el).data('throbber'));
- throbber.show();
- $(id + '-no_components').hide();
- $(id + '-too_many_components').hide();
- $(id + '-error').hide();
- var url = 'rest/prod_comp_search/' + encodeURIComponent(request.term) +
- '?limit=' + (el.data('max_results') + 1);
- if (BUGZILLA.api_token) {
- url += '&Bugzilla_api_token=' + encodeURIComponent(BUGZILLA.api_token);
- }
- $.ajax({
- url: url,
- contentType: 'application/json'
- })
- .done(function(data) {
- throbber.hide();
- if (data.error) {
- $(id + '-error').show();
- console.log(data.message);
- return false;
- }
- if (data.products.length === 0) {
- $(id + '-no_results').show();
- $(document).trigger('pcs:no_results', [ el ]);
- }
- else if (data.products.length > el.data('max_results')) {
- $(id + '-too_many_results').show();
- $(document).trigger('pcs:too_many_results', [ el ]);
- }
- else {
- $(document).trigger('pcs:results', [ el, data ]);
- }
- var current_product = "";
- var prod_comp_array = [];
- var base_params = [];
- if (el.data('format')) {
- base_params.push('format=' + encodeURIComponent(el.data('format')));
- }
- if (el.data('cloned_bug_id')) {
- base_params.push('cloned_bug_id=' + encodeURIComponent(el.data('cloned_bug_id')));
- }
- $.each(data.products, function() {
- var params = base_params.slice();
- params.push('product=' + encodeURIComponent(this.product));
- if (this.product != current_product) {
- prod_comp_array.push({
- label: this.product,
- product: this.product,
- url: el.data('script_name') + '?' + params.join('&')
- });
- current_product = this.product;
+
+ function hideNotifications(target) {
+ var id = '#' + $(target).prop('id');
+ var that = $(id);
+ if (that.data('counter') === 0)
+ that.removeClass('autocomplete-running');
+ $(id + '-no_results').hide();
+ $(id + '-too_many_results').hide();
+ $(id + '-error').hide();
+ }
+
+ function searchComplete(query, suggestions) {
+ var that = $(this);
+ var id = '#' + that.prop('id');
+
+ that.data('counter', that.data('counter') - 1);
+ hideNotifications(this);
+ if (document.activeElement != this)
+ that.devbridgeAutocomplete('hide');
+ if (that.data('error')) {
+ searchError.call(that[0], null, null, null, that.data('error'));
+ that.data('error', '');
+ }
+
+ if (suggestions.length === 0) {
+ $(id + '-no_results').show();
+ $(document).trigger('pcs:no_results', [ that ]);
+ }
+ else if (suggestions.length > that.data('max_results')) {
+ $(id + '-too_many_results').show();
+ $(document).trigger('pcs:too_many_results', [ that ]);
+ }
+ else {
+ $(document).trigger('pcs:results', [ that, suggestions ]);
+ }
+ }
+
+ function searchError(q, jqXHR, textStatus, errorThrown) {
+ var that = $(this);
+ that.data('counter', that.data('counter') - 1);
+ hideNotifications(this);
+ if (errorThrown !== 'abort') {
+ $('#' + that.attr('id') + '-error').show();
+ console.log(errorThrown);
+ }
+ }
+
+ $('.prod_comp_search')
+ .each(function() {
+ var that = $(this);
+ that.devbridgeAutocomplete({
+ serviceUrl: function(query) {
+ return 'rest/prod_comp_search/' + encodeURIComponent(query);
+ },
+ params: {
+ Bugzilla_api_token: (BUGZILLA.api_token ? BUGZILLA.api_token : ''),
+ limit: (that.data('max_results') + 1)
+ },
+ deferRequestBy: 250,
+ minChars: 3,
+ maxHeight: 500,
+ tabDisabled: true,
+ autoSelectFirst: true,
+ triggerSelectOnValidInput: false,
+ width: '',
+ transformResult: function(response) {
+ response = $.parseJSON(response);
+ if (response.error) {
+ that.data('error', response.message);
+ return { suggestions: [] };
}
- params.push('component=' + encodeURIComponent(this.component));
- var url = el.data('script_name') + '?' + params.join('&');
- if (el.data('anchor_component')) {
- url += "#" + encodeURIComponent(this.component);
+ return {
+ suggestions: $.map(response.products, function(dataItem) {
+ if (dataItem.component) {
+ return {
+ value: dataItem.product + ' :: ' + dataItem.component,
+ data : dataItem
+ };
+ }
+ else {
+ return {
+ value: dataItem.product,
+ data : dataItem
+ };
+ }
+ })
+ };
+ },
+ formatResult: function(suggestion, currentValue) {
+ var value = (suggestion.data.component ? suggestion.data.component : suggestion.data.product);
+ var escaped = value
+ .replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
+ if (suggestion.data.component) {
+ return '-&nbsp;' + escaped;
}
- prod_comp_array.push({
- label: this.product + ' :: ' + this.component,
- product: this.product,
- component: this.component,
- url: url
- });
- });
- response(prod_comp_array);
- })
- .fail(function(xhr, error_text) {
- if (xhr.responseJSON && xhr.responseJSON.error) {
- error_text = xhr.responseJSON.message;
+ else {
+ return '<b>' + escaped + '</b>';
+ }
+ return suggestion.data.component ? '-&nbsp;' + escaped : escaped;
+ },
+ beforeRender: function(container) {
+ container.css('min-width', that.outerWidth() - 2 + 'px');
+ },
+ onSearchStart: function(params) {
+ var that = $(this);
+ params.match = $.trim(params.match);
+ that.addClass('autocomplete-running');
+ that.data('counter', that.data('counter') + 1);
+ that.data('error', '');
+ hideNotifications(this);
+ },
+ onSearchComplete: searchComplete,
+ onSearchError: searchError,
+ onSelect: function(suggestion) {
+ var that = $(this);
+ if (that.data('ignore-select'))
+ return;
+
+ var params = [];
+ if (that.data('format'))
+ params.push('format=' + encodeURIComponent(that.data('format')));
+ if (that.data('cloned_bug_id'))
+ params.push('cloned_bug_id=' + encodeURIComponent(that.data('cloned_bug_id')));
+ params.push('product=' + encodeURIComponent(suggestion.data.product));
+ if (suggestion.data.component)
+ params.push('component=' + encodeURIComponent(suggestion.data.component));
+
+ var url = that.data('script_name') + '?' + params.join('&');
+ if (that.data('anchor_component') && suggestion.data.component)
+ url += "#" + encodeURIComponent(suggestion.data.component);
+ document.location.href = url;
}
- throbber.hide();
- $(id + '-comp_error').show();
- $(document).trigger('pcs:error', [ el, error_text ]);
- console.log(error_text);
});
- },
- focus: function(event, ui) {
- event.preventDefault();
- },
- select: function(event, ui) {
- event.preventDefault();
- var el = $(this);
- el.val(ui.item.label);
- if (el.data('ignore-select')) {
- return;
- }
- if (el.data('new_tab')) {
- window.open(ui.item.url, '_blank');
- }
- else {
- window.location.href = ui.item.url;
- }
- }
- })
- .focus(function(event) {
- var el = $(event.target);
- if (el.val().length >= el.autocomplete('option', 'minLength')) {
- el.autocomplete('search');
- }
- });
- $('.prod_comp_search:focus').select();
+ })
+ .data('counter', 0);
});
diff --git a/extensions/REMO/template/en/default/bug/create/create-mozreps.html.tmpl b/extensions/REMO/template/en/default/bug/create/create-mozreps.html.tmpl
index 6a5794121..286beefaa 100644
--- a/extensions/REMO/template/en/default/bug/create/create-mozreps.html.tmpl
+++ b/extensions/REMO/template/en/default/bug/create/create-mozreps.html.tmpl
@@ -23,7 +23,6 @@
title = "Mozilla Reps - Application Form"
generate_api_token = 1
style_urls = [ "extensions/REMO/web/styles/moz_reps.css" ]
- yui = [ "autocomplete" ]
jquery = []
javascript_urls = [ "extensions/REMO/web/js/moz_reps.js", "js/field.js", "js/util.js"]
%]
diff --git a/extensions/REMO/template/en/default/bug/create/create-remo-budget.html.tmpl b/extensions/REMO/template/en/default/bug/create/create-remo-budget.html.tmpl
index 5f5291d32..873ca9503 100644
--- a/extensions/REMO/template/en/default/bug/create/create-remo-budget.html.tmpl
+++ b/extensions/REMO/template/en/default/bug/create/create-remo-budget.html.tmpl
@@ -15,7 +15,7 @@
javascript_urls = [ 'extensions/REMO/web/js/form_validate.js',
'js/util.js',
'js/field.js' ]
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
%]
[% IF user.in_group("mozilla-reps") %]
diff --git a/extensions/Review/template/en/default/pages/review_history.html.tmpl b/extensions/Review/template/en/default/pages/review_history.html.tmpl
index 98acf4cb8..107f69f70 100644
--- a/extensions/Review/template/en/default/pages/review_history.html.tmpl
+++ b/extensions/Review/template/en/default/pages/review_history.html.tmpl
@@ -17,7 +17,6 @@
'extensions/Review/web/js/moment.min.js',
'js/util.js',
'js/field.js' ]
- yui = [ "autocomplete" ]
%]
<script type="text/javascript">
diff --git a/extensions/Splinter/template/en/default/pages/splinter.html.tmpl b/extensions/Splinter/template/en/default/pages/splinter.html.tmpl
index bfb6e2fcb..14034a184 100644
--- a/extensions/Splinter/template/en/default/pages/splinter.html.tmpl
+++ b/extensions/Splinter/template/en/default/pages/splinter.html.tmpl
@@ -41,7 +41,6 @@
"extensions/Splinter/web/splinter.js",
"js/field.js" ]
bodyclasses = bodyclasses
- yui = ['autocomplete']
%]
[% can_edit = 0 %]
diff --git a/extensions/UserProfile/template/en/default/pages/user_profile.html.tmpl b/extensions/UserProfile/template/en/default/pages/user_profile.html.tmpl
index 617ee1f2b..9cbf80c8a 100644
--- a/extensions/UserProfile/template/en/default/pages/user_profile.html.tmpl
+++ b/extensions/UserProfile/template/en/default/pages/user_profile.html.tmpl
@@ -17,7 +17,6 @@
title = "User Profile: $filtered_identity"
generate_api_token = 1
style_urls = [ "extensions/UserProfile/web/styles/user_profile.css" ]
- yui = [ 'autocomplete' ]
javascript_urls = [ "js/field.js" ]
%]
diff --git a/js/comment-tagging.js b/js/comment-tagging.js
index 1c96e5bb3..3897d46b8 100644
--- a/js/comment-tagging.js
+++ b/js/comment-tagging.js
@@ -34,40 +34,27 @@ YAHOO.bugzilla.commentTagging = {
});
if (!can_edit) return;
- var ds = new YAHOO.util.XHRDataSource("jsonrpc.cgi");
- ds.connTimeout = 30000;
- ds.connMethodPost = true;
- ds.connXhrMode = "cancelStaleRequests";
- ds.maxCacheEntries = 5;
- ds.responseSchema = {
- metaFields : { error: "error", jsonRpcId: "id"},
- resultsList : "result"
- };
-
- var ac = new YAHOO.widget.AutoComplete('bz_ctag_add', 'bz_ctag_autocomp', ds);
- ac.maxResultsDisplayed = 7;
- ac.generateRequest = function(query) {
- query = YAHOO.lang.trim(query);
- YAHOO.bugzilla.commentTagging.last_query = query;
- YAHOO.bugzilla.commentTagging.counter = YAHOO.bugzilla.commentTagging.counter + 1;
- YAHOO.util.Connect.setDefaultPostHeader('application/json', true);
- return YAHOO.lang.JSON.stringify({
- version: "1.1",
- method : "Bug.search_comment_tags",
- id : YAHOO.bugzilla.commentTagging.counter,
- params : {
- Bugzilla_api_token: BUGZILLA.api_token,
- query : query,
- limit : 10
- }
- });
- };
- ac.minQueryLength = this.min_len;
- ac.autoHighlight = false;
- ac.typeAhead = true;
- ac.queryDelay = 0.5;
- ac.dataReturnEvent.subscribe(function(type, args) {
- args[0].autoHighlight = args[2].length == 1;
+ $('#bz_ctag_add').devbridgeAutocomplete({
+ serviceUrl: function(query) {
+ return 'rest/bug/comment/tags/' + encodeURIComponent(query);
+ },
+ params: {
+ Bugzilla_api_token: BUGZILLA.api_token
+ },
+ deferRequestBy: 250,
+ minChars: 1,
+ tabDisabled: true,
+ transformResult: function(response) {
+ response = $.parseJSON(response);
+ return {
+ suggestions: $.map(response, function(dataItem) {
+ return {
+ value: dataItem,
+ data : null
+ };
+ })
+ };
+ }
});
},
diff --git a/js/field.js b/js/field.js
index b35cfe782..778451daf 100644
--- a/js/field.js
+++ b/js/field.js
@@ -696,116 +696,122 @@ function browserCanHideOptions(aSelect) {
/* (end) option hiding code */
/**
- * The Autoselect
+ * Autocompletion
*/
-YAHOO.bugzilla.userAutocomplete = {
- counter : 0,
- dataSource : null,
- generateRequest : function ( enteredText ){
- YAHOO.bugzilla.userAutocomplete.counter =
- YAHOO.bugzilla.userAutocomplete.counter + 1;
- YAHOO.util.Connect.setDefaultPostHeader('application/json', true);
- var json_object = {
- method : "User.get",
- id : YAHOO.bugzilla.userAutocomplete.counter,
- params : [ {
+
+$(function() {
+
+ // single user
+
+ function searchComplete() {
+ var that = $(this);
+ that.data('counter', that.data('counter') - 1);
+ if (that.data('counter') === 0)
+ that.removeClass('autocomplete-running');
+ if (document.activeElement != this)
+ that.devbridgeAutocomplete('hide');
+ };
+
+ var options_user = {
+ serviceUrl: 'rest/user',
+ params: {
Bugzilla_api_token: BUGZILLA.api_token,
- match : [ decodeURIComponent(enteredText) ],
- include_fields : [ "name", "real_name" ]
- } ]
- };
- var stringified = YAHOO.lang.JSON.stringify(json_object);
- var debug = { msg: "json-rpc obj debug info", "json obj": json_object,
- "param" : stringified}
- YAHOO.bugzilla.userAutocomplete.debug_helper( debug );
- return stringified;
- },
- resultListFormat : function(oResultData, enteredText, sResultMatch) {
- return ( YAHOO.lang.escapeHTML(oResultData.real_name) + " ("
- + YAHOO.lang.escapeHTML(oResultData.name) + ")");
- },
- debug_helper : function ( ){
- /* used to help debug any errors that might happen */
- /*
- if( typeof(console) !== 'undefined' && console != null && arguments.length > 0 ){
- console.log("debug helper info:", arguments);
- }
- */
- return true;
- },
- init_ds : function(){
- this.dataSource = new YAHOO.util.XHRDataSource("jsonrpc.cgi");
- this.dataSource.connTimeout = 30000;
- this.dataSource.connMethodPost = true;
- this.dataSource.connXhrMode = "cancelStaleRequests";
- this.dataSource.maxCacheEntries = 5;
- this.dataSource.responseSchema = {
- resultsList : "result.users",
- metaFields : { error: "error", jsonRpcId: "id"},
- fields : [
- { key : "name" },
- { key : "real_name"}
- ]
- };
- },
- init : function( field, container, multiple ) {
- if( this.dataSource == null ){
- this.init_ds();
- }
- var userAutoComp = new YAHOO.widget.AutoComplete( field, container,
- this.dataSource );
- // other stuff we might want to do with the autocomplete goes here
- userAutoComp.maxResultsDisplayed = BUGZILLA.param.maxusermatches;
- userAutoComp.generateRequest = this.generateRequest;
- userAutoComp.formatResult = this.resultListFormat;
- userAutoComp.doBeforeLoadData = this.debug_helper;
- userAutoComp.minQueryLength = 3;
- userAutoComp.autoHighlight = false;
- // this is a throttle to determine the delay of the query from typing
- // set this higher to cause fewer calls to the server
- userAutoComp.queryDelay = 0.05;
- userAutoComp.useIFrame = true;
- userAutoComp.resultTypeList = false;
- if( multiple == true ){
- userAutoComp.delimChar = [","];
- }
-
- }
-};
+ include_fields: 'name,real_name',
+ limit: 100
+ },
+ paramName: 'match',
+ deferRequestBy: 250,
+ minChars: 3,
+ tabDisabled: true,
+ autoSelectFirst: true,
+ transformResult: function(response) {
+ response = $.parseJSON(response);
+ return {
+ suggestions: $.map(response.users, function(dataItem) {
+ return {
+ value: dataItem.name,
+ data : { login: dataItem.name, name: dataItem.real_name }
+ };
+ })
+ };
+ },
+ formatResult: function(suggestion, currentValue) {
+ return (suggestion.data.name === '' ?
+ suggestion.data.login : suggestion.data.name + ' (' + suggestion.data.login + ')')
+ .replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
+ },
+ onSearchStart: function(params) {
+ var that = $(this);
+
+ // adding spaces shouldn't initiate a new search
+ var query;
+ if (that.data('multiple')) {
+ var parts = that.val().split(/,\s*/);
+ query = parts[parts.length - 1];
+ }
+ else {
+ query = params.match;
+ }
+ if (query !== $.trim(query))
+ return false;
-YAHOO.bugzilla.keywordAutocomplete = {
- dataSource : null,
- init_ds : function(){
- this.dataSource = new YAHOO.util.LocalDataSource( YAHOO.bugzilla.keyword_array );
- },
- init : function( field, container ) {
- if( this.dataSource == null ){
- this.init_ds();
- }
- var keywordAutoComp = new YAHOO.widget.AutoComplete(field, container, this.dataSource);
- keywordAutoComp.maxResultsDisplayed = YAHOO.bugzilla.keyword_array.length;
- keywordAutoComp.formatResult = keywordAutoComp.formatEscapedResult;
- keywordAutoComp.minQueryLength = 0;
- keywordAutoComp.useIFrame = true;
- keywordAutoComp.delimChar = [","," "];
- keywordAutoComp.resultTypeList = false;
- keywordAutoComp.queryDelay = 0;
- /* Causes all the possibilities in the keyword to appear when a user
- * focuses on the textbox
- */
- keywordAutoComp.textboxFocusEvent.subscribe( function(){
- var sInputValue = YAHOO.util.Dom.get('keywords').value;
- if( sInputValue.length === 0 ){
- this.sendQuery(sInputValue);
- this.collapseContainer();
- this.expandContainer();
+ that.addClass('autocomplete-running');
+ that.data('counter', that.data('counter') + 1);
+ },
+ onSearchComplete: searchComplete,
+ onSearchError: searchComplete
+ };
+
+ // multiple users (based on single user)
+ var options_users = {
+ delimiter: /,\s*/,
+ onSelect: function() {
+ this.value = this.value + ', ';
+ this.focus();
+ },
+ };
+ $.extend(options_users, options_user);
+
+ // init user autocomplete fields
+ $('.bz_autocomplete_user')
+ .each(function() {
+ var that = $(this);
+ that.data('counter', 0);
+ if (that.data('multiple')) {
+ that.devbridgeAutocomplete(options_users);
+ }
+ else {
+ that.devbridgeAutocomplete(options_user);
}
});
- keywordAutoComp.dataRequestEvent.subscribe( function(type, args) {
- args[0].autoHighlight = args[1] != '';
+
+ // init autocomplete fields with array of values
+ $('.bz_autocomplete_values')
+ .each(function() {
+ var that = $(this);
+ that.devbridgeAutocomplete({
+ lookup: BUGZILLA.autocomplete_values[that.data('values')],
+ tabDisabled: true,
+ delimiter: /,\s*/,
+ minChars: 0,
+ autoSelectFirst: true,
+ formatResult: function(suggestion, currentValue) {
+ // disable <b> wrapping of matched substring
+ return suggestion.value
+ .replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
+ },
+ onSelect: function() {
+ this.focus();
+ }
+ });
});
- }
-};
+});
/**
* Force the browser to honour the selected option when a page is refreshed,
diff --git a/js/jquery/plugins/devbridgeAutocomplete/devbridgeAutocomplete-min.js b/js/jquery/plugins/devbridgeAutocomplete/devbridgeAutocomplete-min.js
new file mode 100644
index 000000000..01623ab8c
--- /dev/null
+++ b/js/jquery/plugins/devbridgeAutocomplete/devbridgeAutocomplete-min.js
@@ -0,0 +1,8 @@
+/**
+* Ajax Autocomplete for jQuery, version 1.2.18
+* (c) 2014 Tomas Kirda
+*
+* Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
+* For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete
+*/
+!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports&&"function"==typeof require?require("jquery"):jQuery)}(function(a){"use strict";function b(c,d){var e=function(){},f=this,g={ajaxSettings:{},autoSelectFirst:!1,appendTo:document.body,serviceUrl:null,lookup:null,onSelect:null,width:"auto",minChars:1,maxHeight:300,deferRequestBy:0,params:{},formatResult:b.formatResult,delimiter:null,zIndex:9999,type:"GET",noCache:!1,onSearchStart:e,onSearchComplete:e,onSearchError:e,preserveInput:!1,containerClass:"autocomplete-suggestions",tabDisabled:!1,dataType:"text",currentRequest:null,triggerSelectOnValidInput:!0,preventBadQueries:!0,lookupFilter:function(a,b,c){return-1!==a.value.toLowerCase().indexOf(c)},paramName:"query",transformResult:function(b){return"string"==typeof b?a.parseJSON(b):b},showNoSuggestionNotice:!1,noSuggestionNotice:"No results",orientation:"bottom",forceFixPosition:!1};f.element=c,f.el=a(c),f.suggestions=[],f.badQueries=[],f.selectedIndex=-1,f.currentValue=f.element.value,f.intervalId=0,f.cachedResponse={},f.onChangeInterval=null,f.onChange=null,f.isLocal=!1,f.suggestionsContainer=null,f.noSuggestionsContainer=null,f.options=a.extend({},g,d),f.classes={selected:"autocomplete-selected",suggestion:"autocomplete-suggestion"},f.hint=null,f.hintValue="",f.selection=null,f.initialize(),f.setOptions(d)}var c=function(){return{escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},createNode:function(a){var b=document.createElement("div");return b.className=a,b.style.position="absolute",b.style.display="none",b}}}(),d={ESC:27,TAB:9,RETURN:13,LEFT:37,UP:38,RIGHT:39,DOWN:40};b.utils=c,a.Autocomplete=b,b.formatResult=function(a,b){var d="("+c.escapeRegExChars(b)+")";return a.value.replace(new RegExp(d,"gi"),"<strong>$1</strong>")},b.prototype={killerFn:null,initialize:function(){var c,d=this,e="."+d.classes.suggestion,f=d.classes.selected,g=d.options;d.element.setAttribute("autocomplete","off"),d.killerFn=function(b){0===a(b.target).closest("."+d.options.containerClass).length&&(d.killSuggestions(),d.disableKillerFn())},d.noSuggestionsContainer=a('<div class="autocomplete-no-suggestion"></div>').html(this.options.noSuggestionNotice).get(0),d.suggestionsContainer=b.utils.createNode(g.containerClass),c=a(d.suggestionsContainer),c.appendTo(g.appendTo),"auto"!==g.width&&c.width(g.width),c.on("mouseover.autocomplete",e,function(){d.activate(a(this).data("index"))}),c.on("mouseout.autocomplete",function(){d.selectedIndex=-1,c.children("."+f).removeClass(f)}),c.on("click.autocomplete",e,function(){d.select(a(this).data("index"))}),d.fixPositionCapture=function(){d.visible&&d.fixPosition()},a(window).on("resize.autocomplete",d.fixPositionCapture),d.el.on("keydown.autocomplete",function(a){d.onKeyPress(a)}),d.el.on("keyup.autocomplete",function(a){d.onKeyUp(a)}),d.el.on("blur.autocomplete",function(){d.onBlur()}),d.el.on("focus.autocomplete",function(){d.onFocus()}),d.el.on("change.autocomplete",function(a){d.onKeyUp(a)}),d.el.on("input.autocomplete",function(a){d.onKeyUp(a)})},onFocus:function(){var a=this;a.fixPosition(),a.options.minChars<=a.el.val().length&&a.onValueChange()},onBlur:function(){this.enableKillerFn()},setOptions:function(b){var c=this,d=c.options;a.extend(d,b),c.isLocal=a.isArray(d.lookup),c.isLocal&&(d.lookup=c.verifySuggestionsFormat(d.lookup)),d.orientation=c.validateOrientation(d.orientation,"bottom"),a(c.suggestionsContainer).css({"max-height":d.maxHeight+"px",width:d.width+"px","z-index":d.zIndex})},clearCache:function(){this.cachedResponse={},this.badQueries=[]},clear:function(){this.clearCache(),this.currentValue="",this.suggestions=[]},disable:function(){var a=this;a.disabled=!0,clearInterval(a.onChangeInterval),a.currentRequest&&a.currentRequest.abort()},enable:function(){this.disabled=!1},fixPosition:function(){var b=this,c=a(b.suggestionsContainer),d=c.parent().get(0);if(d===document.body||b.options.forceFixPosition){var e=b.options.orientation,f=c.outerHeight(),g=b.el.outerHeight(),h=b.el.offset(),i={top:h.top,left:h.left};if("auto"===e){var j=a(window).height(),k=a(window).scrollTop(),l=-k+h.top-f,m=k+j-(h.top+g+f);e=Math.max(l,m)===l?"top":"bottom"}if(i.top+="top"===e?-f:g,d!==document.body){var n,o=c.css("opacity");b.visible||c.css("opacity",0).show(),n=c.offsetParent().offset(),i.top-=n.top,i.left-=n.left,b.visible||c.css("opacity",o).hide()}"auto"===b.options.width&&(i.width=b.el.outerWidth()-2+"px"),c.css(i)}},enableKillerFn:function(){var b=this;a(document).on("click.autocomplete",b.killerFn)},disableKillerFn:function(){var b=this;a(document).off("click.autocomplete",b.killerFn)},killSuggestions:function(){var a=this;a.stopKillSuggestions(),a.intervalId=window.setInterval(function(){a.hide(),a.stopKillSuggestions()},50)},stopKillSuggestions:function(){window.clearInterval(this.intervalId)},isCursorAtEnd:function(){var a,b=this,c=b.el.val().length,d=b.element.selectionStart;return"number"==typeof d?d===c:document.selection?(a=document.selection.createRange(),a.moveStart("character",-c),c===a.text.length):!0},onKeyPress:function(a){var b=this;if(!b.disabled&&!b.visible&&a.which===d.DOWN&&b.currentValue)return void b.suggest();if(!b.disabled&&b.visible){switch(a.which){case d.ESC:b.el.val(b.currentValue),b.hide();break;case d.RIGHT:if(b.hint&&b.options.onHint&&b.isCursorAtEnd()){b.selectHint();break}return;case d.TAB:if(b.hint&&b.options.onHint)return void b.selectHint();if(-1===b.selectedIndex)return void b.hide();if(b.select(b.selectedIndex),b.options.tabDisabled===!1)return;break;case d.RETURN:if(-1===b.selectedIndex)return void b.hide();b.select(b.selectedIndex);break;case d.UP:b.moveUp();break;case d.DOWN:b.moveDown();break;default:return}a.stopImmediatePropagation(),a.preventDefault()}},onKeyUp:function(a){var b=this;if(!b.disabled){switch(a.which){case d.UP:case d.DOWN:return}clearInterval(b.onChangeInterval),b.currentValue!==b.el.val()&&(b.findBestHint(),b.options.deferRequestBy>0?b.onChangeInterval=setInterval(function(){b.onValueChange()},b.options.deferRequestBy):b.onValueChange())}},onValueChange:function(){var b,c=this,d=c.options,e=c.el.val(),f=c.getQuery(e);return c.selection&&c.currentValue!==f&&(c.selection=null,(d.onInvalidateSelection||a.noop).call(c.element)),clearInterval(c.onChangeInterval),c.currentValue=e,c.selectedIndex=-1,d.triggerSelectOnValidInput&&(b=c.findSuggestionIndex(f),-1!==b)?void c.select(b):void(f.length<d.minChars?c.hide():c.getSuggestions(f))},findSuggestionIndex:function(b){var c=this,d=-1,e=b.toLowerCase();return a.each(c.suggestions,function(a,b){return b.value.toLowerCase()===e?(d=a,!1):void 0}),d},getQuery:function(b){var c,d=this.options.delimiter;return d?(c=b.split(d),a.trim(c[c.length-1])):b},getSuggestionsLocal:function(b){var c,d=this,e=d.options,f=b.toLowerCase(),g=e.lookupFilter,h=parseInt(e.lookupLimit,10);return c={suggestions:a.grep(e.lookup,function(a){return g(a,b,f)})},h&&c.suggestions.length>h&&(c.suggestions=c.suggestions.slice(0,h)),c},getSuggestions:function(b){var c,d,e,f,g=this,h=g.options,i=h.serviceUrl;if(h.params[h.paramName]=b,d=h.ignoreParams?null:h.params,h.onSearchStart.call(g.element,h.params)!==!1){if(a.isFunction(h.lookup))return void h.lookup(b,function(a){g.suggestions=a.suggestions,g.suggest(),h.onSearchComplete.call(g.element,b,a.suggestions)});g.isLocal?c=g.getSuggestionsLocal(b):(a.isFunction(i)&&(i=i.call(g.element,b)),e=i+"?"+a.param(d||{}),c=g.cachedResponse[e]),c&&a.isArray(c.suggestions)?(g.suggestions=c.suggestions,g.suggest(),h.onSearchComplete.call(g.element,b,c.suggestions)):g.isBadQuery(b)?h.onSearchComplete.call(g.element,b,[]):(g.currentRequest&&g.currentRequest.abort(),f={url:i,data:d,type:h.type,dataType:h.dataType},a.extend(f,h.ajaxSettings),g.currentRequest=a.ajax(f).done(function(a){var c;g.currentRequest=null,c=h.transformResult(a),g.processResponse(c,b,e),h.onSearchComplete.call(g.element,b,c.suggestions)}).fail(function(a,c,d){h.onSearchError.call(g.element,b,a,c,d)}))}},isBadQuery:function(a){if(!this.options.preventBadQueries)return!1;for(var b=this.badQueries,c=b.length;c--;)if(0===a.indexOf(b[c]))return!0;return!1},hide:function(){var b=this,c=a(b.suggestionsContainer);a.isFunction(b.options.onHide)&&b.visible&&b.options.onHide.call(b.element,c),b.visible=!1,b.selectedIndex=-1,clearInterval(b.onChangeInterval),a(b.suggestionsContainer).hide(),b.signalHint(null)},suggest:function(){if(0===this.suggestions.length)return void(this.options.showNoSuggestionNotice?this.noSuggestions():this.hide());var b,c,d=this,e=d.options,f=e.groupBy,g=e.formatResult,h=d.getQuery(d.currentValue),i=d.classes.suggestion,j=d.classes.selected,k=a(d.suggestionsContainer),l=a(d.noSuggestionsContainer),m=e.beforeRender,n="",o=function(a){var c=a.data[f];return b===c?"":(b=c,'<div class="autocomplete-group"><strong>'+b+"</strong></div>")};return e.triggerSelectOnValidInput&&(c=d.findSuggestionIndex(h),-1!==c)?void d.select(c):(a.each(d.suggestions,function(a,b){f&&(n+=o(b,h,a)),n+='<div class="'+i+'" data-index="'+a+'">'+g(b,h)+"</div>"}),this.adjustContainerWidth(),l.detach(),k.html(n),a.isFunction(m)&&m.call(d.element,k),d.fixPosition(),k.show(),e.autoSelectFirst&&(d.selectedIndex=0,k.scrollTop(0),k.children("."+i).first().addClass(j)),d.visible=!0,void d.findBestHint())},noSuggestions:function(){var b=this,c=a(b.suggestionsContainer),d=a(b.noSuggestionsContainer);this.adjustContainerWidth(),d.detach(),c.empty(),c.append(d),b.fixPosition(),c.show(),b.visible=!0},adjustContainerWidth:function(){var b,c=this,d=c.options,e=a(c.suggestionsContainer);"auto"===d.width&&(b=c.el.outerWidth()-2,e.width(b>0?b:300))},findBestHint:function(){var b=this,c=b.el.val().toLowerCase(),d=null;c&&(a.each(b.suggestions,function(a,b){var e=0===b.value.toLowerCase().indexOf(c);return e&&(d=b),!e}),b.signalHint(d))},signalHint:function(b){var c="",d=this;b&&(c=d.currentValue+b.value.substr(d.currentValue.length)),d.hintValue!==c&&(d.hintValue=c,d.hint=b,(this.options.onHint||a.noop)(c))},verifySuggestionsFormat:function(b){return b.length&&"string"==typeof b[0]?a.map(b,function(a){return{value:a,data:null}}):b},validateOrientation:function(b,c){return b=a.trim(b||"").toLowerCase(),-1===a.inArray(b,["auto","bottom","top"])&&(b=c),b},processResponse:function(a,b,c){var d=this,e=d.options;a.suggestions=d.verifySuggestionsFormat(a.suggestions),e.noCache||(d.cachedResponse[c]=a,e.preventBadQueries&&0===a.suggestions.length&&d.badQueries.push(b)),b===d.getQuery(d.currentValue)&&(d.suggestions=a.suggestions,d.suggest())},activate:function(b){var c,d=this,e=d.classes.selected,f=a(d.suggestionsContainer),g=f.find("."+d.classes.suggestion);return f.find("."+e).removeClass(e),d.selectedIndex=b,-1!==d.selectedIndex&&g.length>d.selectedIndex?(c=g.get(d.selectedIndex),a(c).addClass(e),c):null},selectHint:function(){var b=this,c=a.inArray(b.hint,b.suggestions);b.select(c)},select:function(a){var b=this;b.hide(),b.onSelect(a)},moveUp:function(){var b=this;if(-1!==b.selectedIndex)return 0===b.selectedIndex?(a(b.suggestionsContainer).children().first().removeClass(b.classes.selected),b.selectedIndex=-1,b.el.val(b.currentValue),void b.findBestHint()):void b.adjustScroll(b.selectedIndex-1)},moveDown:function(){var a=this;a.selectedIndex!==a.suggestions.length-1&&a.adjustScroll(a.selectedIndex+1)},adjustScroll:function(b){var c=this,d=c.activate(b);if(d){var e,f,g,h=a(d).outerHeight();e=d.offsetTop,f=a(c.suggestionsContainer).scrollTop(),g=f+c.options.maxHeight-h,f>e?a(c.suggestionsContainer).scrollTop(e):e>g&&a(c.suggestionsContainer).scrollTop(e-c.options.maxHeight+h),c.options.preserveInput||c.el.val(c.getValue(c.suggestions[b].value)),c.signalHint(null)}},onSelect:function(b){var c=this,d=c.options.onSelect,e=c.suggestions[b];c.currentValue=c.getValue(e.value),c.currentValue===c.el.val()||c.options.preserveInput||c.el.val(c.currentValue),c.signalHint(null),c.suggestions=[],c.selection=e,a.isFunction(d)&&d.call(c.element,e)},getValue:function(a){var b,c,d=this,e=d.options.delimiter;return e?(b=d.currentValue,c=b.split(e),1===c.length?a:b.substr(0,b.length-c[c.length-1].length)+a):a},dispose:function(){var b=this;b.el.off(".autocomplete").removeData("autocomplete"),b.disableKillerFn(),a(window).off("resize.autocomplete",b.fixPositionCapture),a(b.suggestionsContainer).remove()}},a.fn.autocomplete=a.fn.devbridgeAutocomplete=function(c,d){var e="autocomplete";return 0===arguments.length?this.first().data(e):this.each(function(){var f=a(this),g=f.data(e);"string"==typeof c?g&&"function"==typeof g[c]&&g[c](d):(g&&g.dispose&&g.dispose(),g=new b(this,c),f.data(e,g))})}}); \ No newline at end of file
diff --git a/js/jquery/plugins/devbridgeAutocomplete/license.txt b/js/jquery/plugins/devbridgeAutocomplete/license.txt
new file mode 100644
index 000000000..11b3ff11a
--- /dev/null
+++ b/js/jquery/plugins/devbridgeAutocomplete/license.txt
@@ -0,0 +1,21 @@
+Copyright 2012 DevBridge and other contributors
+http://www.devbridge.com/projects/autocomplete/jquery/
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/skins/standard/global.css b/skins/standard/global.css
index 0cfec436f..940a4add7 100644
--- a/skins/standard/global.css
+++ b/skins/standard/global.css
@@ -668,17 +668,6 @@ input.required, select.required, span.required_explanation {
background-color: #FFEBEB;
}
-/* jquery-ui overrides */
-
-.ui-autocomplete {
- /* set a max height for autocomplete lists */
- overflow-y: auto;
- overflow-x: hidden;
- max-height: 500px;
- /* hovering over the bottom item increases the height by 1px, resulting in a scrollbar */
- padding-bottom: 1px !important;
-}
-
/* always use our font and size */
.ui-widget {
font-family: inherit !important;
@@ -689,3 +678,33 @@ input.required, select.required, span.required_explanation {
.ui-menu .ui-menu-item {
font-weight: normal !important;
}
+
+/* autocomplete */
+
+.autocomplete-suggestions {
+ border: 1px solid #999;
+ background: #fff;
+ color: #000;
+ overflow-x: hidden;
+ overflow-y: auto;
+ cursor: pointer;
+}
+
+.autocomplete-suggestion {
+ padding: 2px 5px;
+ white-space: nowrap;
+ overflow: hidden;
+ width: 100%;
+ margin-right: 1.5em;
+}
+
+.autocomplete-selected {
+ background: #426fd9;
+ color: #FFF
+}
+
+.autocomplete-running {
+ background-image: url("throbber.gif") !important;
+ background-repeat: no-repeat !important;
+ background-position: right 8px center !important;
+}
diff --git a/skins/standard/throbber.gif b/skins/standard/throbber.gif
new file mode 100644
index 000000000..bc4fa6561
--- /dev/null
+++ b/skins/standard/throbber.gif
Binary files differ
diff --git a/template/en/default/account/prefs/prefs.html.tmpl b/template/en/default/account/prefs/prefs.html.tmpl
index 289a155ea..1fcb3e25a 100644
--- a/template/en/default/account/prefs/prefs.html.tmpl
+++ b/template/en/default/account/prefs/prefs.html.tmpl
@@ -43,7 +43,6 @@
style_urls = ['skins/standard/admin.css']
javascript_urls = ['js/util.js', 'js/field.js', 'js/TUI.js']
doc_section = "userpreferences.html"
- yui = ['autocomplete']
%]
[% tabs = [{ name => "settings", label => "General Preferences",
diff --git a/template/en/default/admin/components/create.html.tmpl b/template/en/default/admin/components/create.html.tmpl
index a95d45399..b6b79f8b6 100644
--- a/template/en/default/admin/components/create.html.tmpl
+++ b/template/en/default/admin/components/create.html.tmpl
@@ -26,7 +26,6 @@
[% title = BLOCK %]Add component to the [% product.name FILTER html %] product[% END %]
[% PROCESS global/header.html.tmpl
- yui = [ 'autocomplete' ]
javascript_urls = [ "js/field.js" ]
title = title
generate_api_token = 1
diff --git a/template/en/default/admin/components/edit.html.tmpl b/template/en/default/admin/components/edit.html.tmpl
index 874310ac8..e1083e7e8 100644
--- a/template/en/default/admin/components/edit.html.tmpl
+++ b/template/en/default/admin/components/edit.html.tmpl
@@ -34,7 +34,6 @@
[% PROCESS global/header.html.tmpl
title = title
generate_api_token = 1
- yui = [ 'autocomplete' ]
javascript_urls = [ "js/field.js" ]
%]
diff --git a/template/en/default/attachment/create.html.tmpl b/template/en/default/attachment/create.html.tmpl
index 0380f7ddd..ff359338a 100644
--- a/template/en/default/attachment/create.html.tmpl
+++ b/template/en/default/attachment/create.html.tmpl
@@ -35,7 +35,6 @@
subheader = subheader
generate_api_token = 1
style_urls = [ 'skins/standard/attachment.css' ]
- yui = [ 'autocomplete' ]
javascript_urls = [ "js/attachment.js", 'js/field.js', "js/util.js", "js/TUI.js" ]
doc_section = "attachments.html"
%]
diff --git a/template/en/default/attachment/edit.html.tmpl b/template/en/default/attachment/edit.html.tmpl
index 9a1763642..6bd75f448 100644
--- a/template/en/default/attachment/edit.html.tmpl
+++ b/template/en/default/attachment/edit.html.tmpl
@@ -41,7 +41,6 @@
doc_section = "attachments.html"
javascript_urls = ['js/attachment.js', 'js/field.js']
style_urls = ['skins/standard/attachment.css']
- yui = [ 'autocomplete' ]
bodyclasses = "no_javascript"
%]
diff --git a/template/en/default/bug/create/create.html.tmpl b/template/en/default/bug/create/create.html.tmpl
index fc1bc5420..b3619f993 100644
--- a/template/en/default/bug/create/create.html.tmpl
+++ b/template/en/default/bug/create/create.html.tmpl
@@ -31,7 +31,7 @@
[% PROCESS global/header.html.tmpl
title = title
generate_api_token = 1
- yui = [ 'autocomplete', 'calendar', 'datatable', 'button' ]
+ yui = [ 'calendar', 'datatable', 'button' ]
style_urls = [ 'skins/standard/attachment.css',
'skins/standard/enter_bug.css',
'skins/custom/create_bug.css' ]
diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl
index 0fc8762a4..eba5702e3 100644
--- a/template/en/default/bug/edit.html.tmpl
+++ b/template/en/default/bug/edit.html.tmpl
@@ -34,11 +34,11 @@
[% IF user.can_tag_comments %]
<div id="bz_ctag_div" class="bz_default_hidden">
<a href="javascript:void(0)" onclick="YAHOO.bugzilla.commentTagging.hideInput()">x</a>
- <div>
+ <span>
<input id="bz_ctag_add" size="10" placeholder="add tag"
maxlength="[% constants.MAX_COMMENT_TAG_LENGTH FILTER html %]">
<span id="bz_ctag_autocomp"></span>
- </div>
+ </span>
[<a href="https://wiki.mozilla.org/BMO/comment_tagging"
target="_blank" title="About Comment Tagging">help</a>]
&nbsp;
diff --git a/template/en/default/bug/field.html.tmpl b/template/en/default/bug/field.html.tmpl
index 366fe1144..ba1237dc0 100644
--- a/template/en/default/bug/field.html.tmpl
+++ b/template/en/default/bug/field.html.tmpl
@@ -235,19 +235,18 @@
[% END %]
[% END %]
[% CASE constants.FIELD_TYPE_KEYWORDS %]
- <div id="keyword_container">
- <input type="text" id="[% field.name FILTER html %]" size="40"
- class="text_input" name="[% field.name FILTER html %]"
- value="[% value FILTER html %]">
- <div id="keyword_autocomplete"></div>
- </div>
- <script type="text/javascript" defer="defer">
- YAHOO.bugzilla.keyword_array = [
- [%- FOREACH keyword = active_keywords %]
- [%-# %]"[% keyword.name FILTER js %]"
- [%- "," IF NOT loop.last %][% END %]];
- YAHOO.bugzilla.keywordAutocomplete.init('[% field.name FILTER js %]',
- 'keyword_autocomplete');
+ <input type="text" id="[% field.name FILTER html %]" size="40"
+ class="text_input bz_autocomplete_values"
+ name="[% field.name FILTER html %]"
+ data-values="[% field.name FILTER html %]"
+ value="[% value FILTER html %]">
+ <script type="text/javascript">
+ if (typeof BUGZILLA.autocomplete_values === 'undefined')
+ BUGZILLA.autocomplete_values = [];
+ BUGZILLA.autocomplete_values['[% field.name FILTER js %]'] = [
+ [%- FOREACH keyword = active_keywords %]
+ [%- %]"[% keyword.name FILTER js %]"
+ [%- "," IF NOT loop.last %][% END %]];
</script>
[% CASE constants.FIELD_TYPE_EXTENSION %]
[% Hook.process('editable') %]
diff --git a/template/en/default/bug/show-header.html.tmpl b/template/en/default/bug/show-header.html.tmpl
index 6170d7a45..e7d0a07fb 100644
--- a/template/en/default/bug/show-header.html.tmpl
+++ b/template/en/default/bug/show-header.html.tmpl
@@ -39,7 +39,7 @@
[% generate_api_token = 1 %]
[% header = "$terms.Bug&nbsp;$bug.bug_id" %]
[% header_addl_info = "Last modified: $filtered_timestamp" %]
-[% yui = ['autocomplete', 'calendar'] %]
+[% yui = ['calendar', 'connection', 'json'] %]
[% yui.push('container') IF user.can_tag_comments %]
[% javascript_urls = [ "js/util.js", "js/field.js" ] %]
[% javascript_urls.push("js/bug.js") IF user.id %]
diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl
index 5528a96c2..086191a39 100644
--- a/template/en/default/global/header.html.tmpl
+++ b/template/en/default/global/header.html.tmpl
@@ -58,7 +58,6 @@
[% IF NOT no_yui %]
[% SET yui_css = {
- autocomplete => 1,
calendar => 1,
datatable => 1,
button => 1,
@@ -69,7 +68,6 @@
# if that module is going to be specified in "yui".
#%]
[% SET yui_deps = {
- autocomplete => ['json', 'connection', 'datasource'],
datatable => ['json', 'connection', 'datasource', 'element'],
} %]
@@ -101,8 +99,8 @@
] %]
[% style_urls.import(jquery_css, jq_css_urls) FILTER null %]
-[%# Add jQuery cookie support %]
-[% jquery.push("cookie") %]
+[%# Add our required jQuery plugins %]
+[% jquery.push("cookie", "devbridgeAutocomplete") %]
[%# We should be able to set the default value of the header variable
# to the value of the title variable using the DEFAULT directive,
diff --git a/template/en/default/global/userselect.html.tmpl b/template/en/default/global/userselect.html.tmpl
index d7b4786f9..f7dc03d89 100644
--- a/template/en/default/global/userselect.html.tmpl
+++ b/template/en/default/global/userselect.html.tmpl
@@ -1,19 +1,9 @@
-[%# The contents of this file are subject to the Mozilla Public
- # License Version 1.1 (the "License"); you may not use this file
- # except in compliance with the License. You may obtain a copy of
- # the License at http://www.mozilla.org/MPL/
+[%# 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/.
#
- # Software distributed under the License is distributed on an "AS
- # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- # implied. See the License for the specific language governing
- # rights and limitations under the License.
- #
- # The Original Code is the Bugzilla Bug Tracking System.
- #
- # Contributor(s): Byron Jones <bugzilla@glob.com.au>
- # Frédéric Buclin <LpSolit@gmail.com>
- # Guy Pyrzak <guy.pyrzak@gmail.com>
- # Reed Loden <reed@reedloden.com>
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
#%]
[%# INTERFACE:
@@ -31,6 +21,7 @@
# custom_userlist: optional, specify a limited list of users to use
# field_title: optional, extra information to display as a tooltip
# placeholder: optional, input only; placeholder attribute value
+ # mandatory: optional; if true, the field cannot be empty.
#%]
[% IF Param("usemenuforusers") %]
@@ -42,6 +33,7 @@
[% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
[% IF multiple %] multiple="multiple" size="[% multiple FILTER html %]" [% END %]
[% IF field_title %] title="[% field_title FILTER html %]" [% END %]
+ [% IF mandatory %] required [% END %]
>
[% IF emptyok %]
<option value=""></option>
@@ -54,12 +46,14 @@
[% custom_userlist = user.get_userlist %]
[% END %]
- [% SET selected = {} %]
- [% IF value.defined %]
- [% FOREACH selected_value IN value.split(', ') %]
- [% SET selected.$selected_value = 1 %]
- [% END %]
- [% END %]
+ [%
+ SET selected = {};
+ IF value.defined;
+ FOREACH selected_value IN value.split(', ');
+ SET selected.$selected_value = 1;
+ END;
+ END;
+ %]
[% FOREACH tmpuser = custom_userlist %]
[% IF tmpuser.visible OR selected.${tmpuser.login} == 1 %]
@@ -80,10 +74,14 @@
[% END %]
</select>
[% ELSE %]
- [% IF feature_enabled('jsonrpc') && Param('ajax_user_autocompletion') && id %]
- <div id="[% id FILTER html %]_autocomplete"
- [% IF classes %] class="[% classes.join(' ') FILTER html %]" [% END %]>
- [% END %]
+ [%
+ IF id && feature_enabled('jsonrpc') && Param('ajax_user_autocompletion');
+ IF !classes.defined;
+ classes = [];
+ END;
+ classes.push("bz_autocomplete_user");
+ END;
+ %]
<input
name="[% name FILTER html %]"
value="[% value FILTER html %]"
@@ -95,17 +93,7 @@
[% IF size %] size="[% size FILTER html %]" [% END %]
[% IF placeholder %] placeholder="[% placeholder FILTER html %]" [% END %]
[% IF id %] id="[% id FILTER html %]" [% END %]
+ [% IF mandatory %] required [% END %]
+ [% IF multiple %] data-multiple="1" [% END %]
>
- [% IF feature_enabled('jsonrpc') && Param('ajax_user_autocompletion') && id %]
- <div id="[% id FILTER html %]_autocomplete_container"></div>
- </div>
- <script type="text/javascript">
- if( typeof(YAHOO.bugzilla.userAutocomplete) !== 'undefined'
- && YAHOO.bugzilla.userAutocomplete != null){
- YAHOO.bugzilla.userAutocomplete.init( "[% id FILTER js %]",
- "[% id FILTER js %]_autocomplete_container"
- [% IF multiple %], true[% END%]);
- }
- </script>
- [% END %]
[% END %]
diff --git a/template/en/default/list/list.html.tmpl b/template/en/default/list/list.html.tmpl
index 73e58c30f..0920a0669 100644
--- a/template/en/default/list/list.html.tmpl
+++ b/template/en/default/list/list.html.tmpl
@@ -48,7 +48,7 @@
generate_api_token = dotweak
style = style
atomlink = "buglist.cgi?$urlquerypart&title=$url_filtered_title&ctype=atom"
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
javascript_urls = [ "js/util.js", "js/field.js" ]
style_urls = [ "skins/standard/buglist.css" ]
doc_section = "query.html#list"
diff --git a/template/en/default/request/queue.html.tmpl b/template/en/default/request/queue.html.tmpl
index d1920a132..64353b4dc 100644
--- a/template/en/default/request/queue.html.tmpl
+++ b/template/en/default/request/queue.html.tmpl
@@ -29,7 +29,6 @@
onload="var f = document.request_form; selectProduct(f.product, f.component, null, null, 'Any');"
javascript_urls=["js/productform.js", "js/field.js"]
style_urls = ['skins/standard/buglist.css']
- yui = ['autocomplete']
%]
<script type="text/javascript">
diff --git a/template/en/default/search/field.html.tmpl b/template/en/default/search/field.html.tmpl
index ae7ca1ad4..d7cdfe886 100644
--- a/template/en/default/search/field.html.tmpl
+++ b/template/en/default/search/field.html.tmpl
@@ -56,20 +56,19 @@
types = types,
selected = type_selected
%]
- <div id="keyword_container">
- <input name="[% field.name FILTER html %]"
- id="[% field.name FILTER html %]" size="40"
- [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
- value="[% value FILTER html %]">
- <div id="keyword_autocomplete"></div>
- </div>
- <script type="text/javascript" defer="defer">
- YAHOO.bugzilla.keyword_array = [
+ <input name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]" size="40"
+ class="bz_autocomplete_values"
+ [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
+ value="[% value FILTER html %]"
+ data-values="[% field.name FILTER html %]">
+ <script type="text/javascript">
+ if (typeof BUGZILLA.autocomplete_values === 'undefined')
+ BUGZILLA.autocomplete_values = [];
+ BUGZILLA.autocomplete_values['[% field.name FILTER js %]'] = [
[%- FOREACH keyword = all_keywords %]
[%-# %]"[% keyword.name FILTER js %]"
[%- "," IF NOT loop.last %][% END %]];
- YAHOO.bugzilla.keywordAutocomplete.init('[% field.name FILTER js %]',
- 'keyword_autocomplete');
</script>
[% CASE [constants.FIELD_TYPE_DATETIME, constants.FIELD_TYPE_DATE] %]
[% INCLUDE "bug/field-label.html.tmpl"
diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl
index 1b9b8310f..2e36eb9e3 100644
--- a/template/en/default/search/form.html.tmpl
+++ b/template/en/default/search/form.html.tmpl
@@ -344,19 +344,11 @@ TUI_hide_default('information_query');
[% " selected" IF default.emailtype.$n == qv.name %]>[% qv.description %]</option>
[% END %]
</select>
- [% IF feature_enabled('jsonrpc') && Param('ajax_user_autocompletion') %]
- <div id="email[% n %]_autocomplete">
- [% END %]
- <input name="email[% n %]" class="email" id="email[% n %]"
- value="[% default.email.$n FILTER html %]">
- [% IF feature_enabled('jsonrpc') && Param('ajax_user_autocompletion') %]
- <div id="email[% n %]_autocomplete_container"></div>
- </div>
- <script type="text/javascript">
- YAHOO.bugzilla.userAutocomplete.init( "email[% n %]",
- "email[% n %]_autocomplete_container");
- </script>
- [% END %]
+ <input
+ name="email[% n %]"
+ class="email [% "bz_autocomplete_user" IF feature_enabled('jsonrpc') && Param('ajax_user_autocompletion') %]"
+ id="email[% n %]"
+ value="[% default.email.$n FILTER html %]">
</div>
[% END %]
[% Hook.process('email_numbering_end') %]
diff --git a/template/en/default/search/search-advanced.html.tmpl b/template/en/default/search/search-advanced.html.tmpl
index f42a9cb00..04ab3d06f 100644
--- a/template/en/default/search/search-advanced.html.tmpl
+++ b/template/en/default/search/search-advanced.html.tmpl
@@ -45,7 +45,7 @@ function remove_token() {
generate_api_token = 1
onload = "doOnSelectProduct(0);"
javascript = js_data
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
javascript_urls = [ "js/productform.js", "js/util.js", "js/TUI.js", "js/field.js"]
style_urls = [ "skins/standard/search_form.css" ]
doc_section = "query.html"
diff --git a/template/en/default/search/search-create-series.html.tmpl b/template/en/default/search/search-create-series.html.tmpl
index 85d54e51c..6b7678b23 100644
--- a/template/en/default/search/search-create-series.html.tmpl
+++ b/template/en/default/search/search-create-series.html.tmpl
@@ -34,7 +34,7 @@
title = "Create New Data Set"
generate_api_token = 1
onload = "doOnSelectProduct(0);"
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
javascript = js_data
javascript_urls = [ "js/util.js", "js/productform.js", "js/TUI.js", "js/field.js" ]
style_urls = [ "skins/standard/search_form.css" ]
diff --git a/template/en/default/search/search-report-graph.html.tmpl b/template/en/default/search/search-report-graph.html.tmpl
index 383e10220..20e8e184d 100644
--- a/template/en/default/search/search-report-graph.html.tmpl
+++ b/template/en/default/search/search-report-graph.html.tmpl
@@ -33,7 +33,7 @@ var queryform = "reportform"
title = "Generate Graphical Report"
generate_api_token = 1
onload = "doOnSelectProduct(0); chartTypeChanged()"
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
javascript = js_data
javascript_urls = [ "js/util.js", "js/productform.js", "js/TUI.js", "js/field.js" ]
style_urls = [ "skins/standard/search_form.css" ]
diff --git a/template/en/default/search/search-report-table.html.tmpl b/template/en/default/search/search-report-table.html.tmpl
index 872773b07..7ff54b8da 100644
--- a/template/en/default/search/search-report-table.html.tmpl
+++ b/template/en/default/search/search-report-table.html.tmpl
@@ -33,7 +33,7 @@ var queryform = "reportform"
title = "Generate Tabular Report"
generate_api_token = 1
onload = "doOnSelectProduct(0)"
- yui = [ 'autocomplete', 'calendar' ]
+ yui = [ 'calendar' ]
javascript = js_data
javascript_urls = [ "js/util.js", "js/productform.js", "js/TUI.js", "js/field.js" ]
style_urls = [ "skins/standard/search_form.css" ]