diff options
-rw-r--r-- | js/field.js | 48 | ||||
-rw-r--r-- | js/show_bug.js | 42 | ||||
-rw-r--r-- | js/util.js | 49 | ||||
-rw-r--r-- | template/en/default/bug/show-header.html.tmpl | 5 |
4 files changed, 101 insertions, 43 deletions
diff --git a/js/field.js b/js/field.js index ede2e43b9..a17fbbb3a 100644 --- a/js/field.js +++ b/js/field.js @@ -795,3 +795,51 @@ YAHOO.bugzilla.keywordAutocomplete = { }); } }; + +/** + * Force the browser to honour the selected option when a page is refreshed, + * but only if the user hasn't explicitly selected a different option. + */ +function initDirtyFieldTracking() { + // old IE versions don't provide the information we need to make this fix work + // however they aren't affected by this issue, so it's ok to ignore them + if (YAHOO.env.ua.ie > 0 && YAHOO.env.ua.ie <= 8) return; + var selects = document.getElementById('changeform').getElementsByTagName('select'); + for (var i = 0, l = selects.length; i < l; i++) { + var el = selects[i]; + var el_dirty = document.getElementById(el.name + '_dirty'); + if (!el_dirty) continue; + if (!el_dirty.value) { + var preSelected = bz_preselectedOptions(el); + if (!el.multiple) { + preSelected.selected = true; + } else { + el.selectedIndex = -1; + for (var j = 0, m = preSelected.length; j < m; j++) { + preSelected[j].selected = true; + } + } + } + YAHOO.util.Event.on(el, "change", function(e) { + var el = e.target || e.srcElement; + var preSelected = bz_preselectedOptions(el); + var currentSelected = bz_selectedOptions(el); + var isDirty = false; + if (!el.multiple) { + isDirty = preSelected.index != currentSelected.index; + } else { + if (preSelected.length != currentSelected.length) { + isDirty = true; + } else { + for (var i = 0, l = preSelected.length; i < l; i++) { + if (currentSelected[i].index != preSelected[i].index) { + isDirty = true; + break; + } + } + } + } + document.getElementById(el.name + '_dirty').value = isDirty ? '1' : ''; + }); + } +} diff --git a/js/show_bug.js b/js/show_bug.js deleted file mode 100644 index 07276075f..000000000 --- a/js/show_bug.js +++ /dev/null @@ -1,42 +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. */ - -function getPreSelectedIndex(el) { - var options = el.options; - for (var i = 0, l = options.length; i < l; i++) { - var attributes = options[i].attributes; - for (var j = 0, m = attributes.length; j < m; j++) { - if (attributes[j].name == 'selected') { - return i; - } - } - } - return -1; -} - -// Force the browser to honour the selected option when a page is refreshed, -// but if the user hasn't explicitly selected a different option. -YAHOO.util.Event.onDOMReady(function() { - var selects = document.getElementById('changeform').getElementsByTagName('select'); - for (var i = 0, l = selects.length; i < l; i++) { - var el = selects[i]; - var el_dirty = document.getElementById(el.name + '_dirty'); - if (el_dirty) { - if (!el_dirty.value) { - var preSelectedIndex = getPreSelectedIndex(el); - if (preSelectedIndex != -1) - el.selectedIndex = preselectedIndex; - } - YAHOO.util.Event.on(el, "change", function(e) { - var el = e.target || e.srcElement; - var preSelectedIndex = getPreSelectedIndex(el); - if (preSelectedIndex != -1) - document.getElementById(el.name + '_dirty').value = preSelectedIndex == el.selectedIndex ? '' : '1'; - }); - } - } -}); diff --git a/js/util.js b/js/util.js index 6dcabbbc9..e0e87259f 100644 --- a/js/util.js +++ b/js/util.js @@ -202,6 +202,55 @@ function bz_populateSelectFromArray(aSelect, aArray) { } /** + * Returns all Option elements that are selected in a <select>, + * as an array. Returns an empty array if nothing is selected. + * + * @param aSelect The select you want the selected values of. + */ +function bz_selectedOptions(aSelect) { + // HTML 5 + if (aSelect.selectedOptions) { + return aSelect.selectedOptions; + } + + var start_at = aSelect.selectedIndex; + if (start_at == -1) return []; + var first_selected = aSelect.options[start_at]; + if (!aSelect.multiple) return first_selected; + // selectedIndex is specified as being the "first selected item", + // so we can start from there. + var selected = [first_selected]; + var options_length = aSelect.options.length; + // We start after first_selected + for (var i = start_at + 1; i < options_length; i++) { + var this_option = aSelect.options[i]; + if (this_option.selected) selected.push(this_option); + } + return selected; +} + +/** + * Returns all Option elements that have the "selected" attribute, as an array. + * Returns an empty array if nothing is selected. + * + * @param aSelect The select you want the pre-selected values of. + */ +function bz_preselectedOptions(aSelect) { + var options = aSelect.options; + var selected = new Array(); + for (var i = 0, l = options.length; i < l; i++) { + var attributes = options[i].attributes; + for (var j = 0, m = attributes.length; j < m; j++) { + if (attributes[j].name == 'selected') { + if (!aSelect.multiple) return options[i]; + selected.push(options[i]); + } + } + } + return selected; +} + +/** * Tells you whether or not a particular value is selected in a select, * whether it's a multi-select or a single-select. The check is * case-sensitive. diff --git a/template/en/default/bug/show-header.html.tmpl b/template/en/default/bug/show-header.html.tmpl index f71c2a22a..40f35ba7c 100644 --- a/template/en/default/bug/show-header.html.tmpl +++ b/template/en/default/bug/show-header.html.tmpl @@ -35,7 +35,7 @@ [% header = "$terms.Bug $bug.bug_id" %] [% header_addl_info = "Last modified: $filtered_timestamp" %] [% yui = ['autocomplete', 'calendar'] %] -[% javascript_urls = [ "js/util.js", "js/field.js", "js/show_bug.js" ] %] +[% javascript_urls = [ "js/util.js", "js/field.js" ] %] [% IF bug.defined %] [% unfiltered_title = "$terms.Bug $bug.bug_id – $bug.short_desc" %] [% javascript = BLOCK %] @@ -52,6 +52,9 @@ history.replaceState(null, "[% unfiltered_title FILTER js %]", href); } } + YAHOO.util.Event.onDOMReady(function() { + initDirtyFieldTracking(); + }); [% javascript FILTER none %] [% END %] [% END %] |