diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/TUI.js | 10 | ||||
-rw-r--r-- | js/comments.js | 27 | ||||
-rw-r--r-- | js/create_bug.js | 116 | ||||
-rw-r--r-- | js/field.js | 7 | ||||
-rw-r--r-- | js/instant-search.js | 201 |
5 files changed, 357 insertions, 4 deletions
@@ -69,8 +69,14 @@ function TUI_hide_default(className) { function _TUI_toggle_control_link(className) { var link = document.getElementById(className + "_controller"); if (!link) return; - var original_text = link.innerHTML; - link.innerHTML = TUI_alternates[className]; + var original_text; + if (link.nodeName == 'INPUT') { + original_text = link.value; + link.value = TUI_alternates[className]; + } else { + original_text = link.innerHTML; + link.innerHTML = TUI_alternates[className]; + } TUI_alternates[className] = original_text; } diff --git a/js/comments.js b/js/comments.js index f46499b62..28ef54397 100644 --- a/js/comments.js +++ b/js/comments.js @@ -145,3 +145,30 @@ function goto_add_comments( anchor ){ },10); return false; } + +if (typeof Node == 'undefined') { + /* MSIE doesn't define Node, so provide a compatibility object */ + window.Node = { + TEXT_NODE: 3, + ENTITY_REFERENCE_NODE: 5 + }; +} + +/* Concatenates all text from element's childNodes. This is used + * instead of innerHTML because we want the actual text (and + * innerText is non-standard). + */ +function getText(element) { + var child, text = ""; + for (var i=0; i < element.childNodes.length; i++) { + child = element.childNodes[i]; + var type = child.nodeType; + if (type == Node.TEXT_NODE || type == Node.ENTITY_REFERENCE_NODE) { + text += child.nodeValue; + } else { + /* recurse into nodes of other types */ + text += getText(child); + } + } + return text; +} diff --git a/js/create_bug.js b/js/create_bug.js new file mode 100644 index 000000000..62d24a642 --- /dev/null +++ b/js/create_bug.js @@ -0,0 +1,116 @@ +function toggleAdvancedFields() { + TUI_toggle_class('expert_fields'); + var elements = YAHOO.util.Dom.getElementsByClassName('expert_fields'); + if (YAHOO.util.Dom.hasClass(elements[0], TUI_HIDDEN_CLASS)) { + handleWantsBugFlags(false); + } +} + +function handleWantsBugFlags(wants) { + if (wants) { + hideElementById('bug_flags_false'); + showElementById('bug_flags_true'); + } + else { + showElementById('bug_flags_false'); + hideElementById('bug_flags_true'); + clearBugFlagFields(); + } +} + +function clearBugFlagFields() { + var flags_table; + flags_table = document.getElementById('bug_flags'); + if (flags_table) { + var selects = flags_table.getElementsByTagName('select'); + for (var i = 0, il = selects.length; i < il; i++) { + if (selects[i].value != 'X') { + selects[i].value = 'X'; + toggleRequesteeField(selects[i]); + } + } + } + flags_table = document.getElementById('bug_tracking_flags'); + if (flags_table) { + var selects = flags_table.getElementsByTagName('select'); + for (var i = 0, il = selects.length; i < il; i++) { + selects[i].value = '---'; + } + } +} + +YAHOO.util.Event.onDOMReady(function() { + function set_width(id, width) { + var el = document.getElementById(id); + if (!el) return; + el.style.width = width + 'px'; + } + + // force field widths + + var width = document.getElementById('short_desc').clientWidth + 'px'; + var el; + + el = document.getElementById('comment'); + el.style.width = width; + + el = document.getElementById('cf_crash_signature'); + if (el) el.style.width = width; + + // show the bug flags if a flag is set + + var flag_set = false; + var flags_table; + flags_table = document.getElementById('bug_flags'); + if (flags_table) { + var selects = flags_table.getElementsByTagName('select'); + for (var i = 0, il = selects.length; i < il; i++) { + if (selects[i].value != 'X') { + flag_set = true; + break; + } + } + } + if (!flag_set) { + flags_table = document.getElementById('bug_tracking_flags'); + if (flags_table) { + var selects = flags_table.getElementsByTagName('select'); + for (var i = 0, il = selects.length; i < il; i++) { + if (selects[i].value != '---') { + flag_set = true; + break; + } + } + } + } + + if (flag_set) { + hideElementById('bug_flags_false'); + showElementById('bug_flags_true'); + } else { + hideElementById('bug_flags_true'); + showElementById('bug_flags_false'); + } + showElementById('btn_no_bug_flags') +}); + +function take_bug(user) { + var el = Dom.get('assigned_to'); + el.value = user; + el.focus(); + el.select(); + assignee_change(user); + return false; +} + +function assignee_change(user) { + var el = Dom.get('take_bug'); + if (!el) return; + el.style.display = Dom.get('assigned_to').value == user ? 'none' : ''; +} + +function init_take_handler(user) { + YAHOO.util.Event.addListener( + 'assigned_to', 'change', function() { assignee_change(user); }); + assignee_change(user); +} diff --git a/js/field.js b/js/field.js index 7cdb50435..8353100f0 100644 --- a/js/field.js +++ b/js/field.js @@ -252,6 +252,8 @@ function showEditableField (e, ContainerInputArray) { inputs.push(inputArea); } else { inputs = inputArea.getElementsByTagName('input'); + if ( inputs.length == 0 ) + inputs = inputArea.getElementsByTagName('textarea'); } if ( inputs.length > 0 ) { // Change the first field's value to ContainerInputArray[2] @@ -273,7 +275,7 @@ function showEditableField (e, ContainerInputArray) { * * var e: the event * var ContainerInputArray: An array containing the (edit) and text area and the input being displayed - * var ContainerInputArray[0]: the conainer that will be hidden usually shows the (edit) text + * var ContainerInputArray[0]: the container that will be hidden usually shows the (edit) text * var ContainerInputArray[1]: the input area and label that will be displayed * var ContainerInputArray[2]: the field that is on the page, might get changed by browser autocomplete * var ContainerInputArray[3]: the original value from the page loading. @@ -684,7 +686,8 @@ YAHOO.bugzilla.userAutocomplete = { id : YAHOO.bugzilla.userAutocomplete.counter, params : [ { match : [ decodeURIComponent(enteredText) ], - include_fields : [ "name", "real_name" ] + include_fields : [ "name", "real_name" ], + include_disabled : 1 } ] }; var stringified = YAHOO.lang.JSON.stringify(json_object); diff --git a/js/instant-search.js b/js/instant-search.js new file mode 100644 index 000000000..a3f051f2f --- /dev/null +++ b/js/instant-search.js @@ -0,0 +1,201 @@ +/* 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. */ + +var Dom = YAHOO.util.Dom; +var Event = YAHOO.util.Event; + +Event.onDOMReady(function() { + YAHOO.bugzilla.instantSearch.onInit(); + if (YAHOO.bugzilla.instantSearch.getContent().length >= 4) { + YAHOO.bugzilla.instantSearch.doSearch(YAHOO.bugzilla.instantSearch.getContent()); + } else { + YAHOO.bugzilla.instantSearch.reset(); + } + Dom.get('content').focus(); +}); + +YAHOO.bugzilla.instantSearch = { + counter: 0, + dataTable: null, + dataTableColumns: null, + elContent: null, + elList: null, + currentSearchQuery: '', + currentSearchProduct: '', + + onInit: function() { + YAHOO.util.Connect.setDefaultPostHeader('application/json; charset=UTF-8'); + + this.elContent = Dom.get('content'); + this.elList = Dom.get('results'); + + Event.addListener(this.elContent, 'keyup', this.onContentKeyUp); + Event.addListener(Dom.get('product'), 'change', this.onProductChange); + }, + + setLabels: function(labels) { + this.dataTableColumns = [ + { key: "id", label: labels.id, formatter: this.formatId }, + { key: "summary", label: labels.summary, formatter: "text" }, + { key: "component", label: labels.component, formatter: "text" }, + { key: "status", label: labels.status, formatter: this.formatStatus }, + ]; + }, + + initDataTable: function() { + var dataSource = new YAHOO.util.XHRDataSource("jsonrpc.cgi"); + dataSource.connTimeout = 15000; + dataSource.connMethodPost = true; + dataSource.connXhrMode = "cancelStaleRequests"; + dataSource.maxCacheEntries = 3; + dataSource.responseSchema = { + resultsList : "result.bugs", + metaFields : { error: "error", jsonRpcId: "id" } + }; + // DataSource can't understand a JSON-RPC error response, so + // we have to modify the result data if we get one. + dataSource.doBeforeParseData = + function(oRequest, oFullResponse, oCallback) { + if (oFullResponse.error) { + oFullResponse.result = {}; + oFullResponse.result.bugs = []; + if (console) + console.error("JSON-RPC error:", oFullResponse.error); + } + return oFullResponse; + }; + dataSource.subscribe('dataErrorEvent', + function() { + YAHOO.bugzilla.instantSearch.currentSearchQuery = ''; + } + ); + + this.dataTable = new YAHOO.widget.DataTable( + 'results', + this.dataTableColumns, + dataSource, + { + initialLoad: false, + MSG_EMPTY: 'No matching bugs found.', + MSG_ERROR: 'An error occurred while searching for bugs, please try again.' + } + ); + }, + + formatId: function(el, oRecord, oColumn, oData) { + el.innerHTML = '<a href="show_bug.cgi?id=' + oData + '" target="_blank">' + oData + '</a>'; + }, + + formatStatus: function(el, oRecord, oColumn, oData) { + var resolution = oRecord.getData('resolution'); + var bugStatus = display_value('bug_status', oData); + if (resolution) { + el.innerHTML = bugStatus + ' ' + display_value('resolution', resolution); + } else { + el.innerHTML = bugStatus; + } + }, + + reset: function() { + Dom.addClass(this.elList, 'hidden'); + this.elList.innerHTML = ''; + this.currentSearchQuery = ''; + this.currentSearchProduct = ''; + }, + + onContentKeyUp: function(e) { + clearTimeout(YAHOO.bugzilla.instantSearch.lastTimeout); + YAHOO.bugzilla.instantSearch.lastTimeout = setTimeout(function() { + YAHOO.bugzilla.instantSearch.doSearch(YAHOO.bugzilla.instantSearch.getContent()) }, + 600); + }, + + onProductChange: function(e) { + YAHOO.bugzilla.instantSearch.doSearch(YAHOO.bugzilla.instantSearch.getContent()); + }, + + doSearch: function(query) { + if (query.length < 4) + return; + + // don't query if we already have the results (or they are pending) + var product = Dom.get('product').value; + if (YAHOO.bugzilla.instantSearch.currentSearchQuery == query && + YAHOO.bugzilla.instantSearch.currentSearchProduct == product) + return; + YAHOO.bugzilla.instantSearch.currentSearchQuery = query; + YAHOO.bugzilla.instantSearch.currentSearchProduct = product; + + // initialise the datatable as late as possible + YAHOO.bugzilla.instantSearch.initDataTable(); + + try { + // run the search + Dom.removeClass(YAHOO.bugzilla.instantSearch.elList, 'hidden'); + + YAHOO.bugzilla.instantSearch.dataTable.showTableMessage( + 'Searching... ' + + '<img src="extensions/GuidedBugEntry/web/images/throbber.gif"' + + ' width="16" height="11">', + YAHOO.widget.DataTable.CLASS_LOADING + ); + var jsonObject = { + version: "1.1", + method: "Bug.possible_duplicates", + id: ++YAHOO.bugzilla.instantSearch.counter, + params: { + product: YAHOO.bugzilla.instantSearch.getProduct(), + summary: query, + limit: 20, + include_fields: [ "id", "summary", "status", "resolution", "component" ] + } + }; + + YAHOO.bugzilla.instantSearch.dataTable.getDataSource().sendRequest( + YAHOO.lang.JSON.stringify(jsonObject), + { + success: YAHOO.bugzilla.instantSearch.onSearchResults, + failure: YAHOO.bugzilla.instantSearch.onSearchResults, + scope: YAHOO.bugzilla.instantSearch.dataTable, + argument: YAHOO.bugzilla.instantSearch.dataTable.getState() + } + ); + + } catch(err) { + if (console) + console.error(err.message); + } + }, + + onSearchResults: function(sRequest, oResponse, oPayload) { + YAHOO.bugzilla.instantSearch.dataTable.onDataReturnInitializeTable(sRequest, oResponse, oPayload); + }, + + getContent: function() { + var content = YAHOO.lang.trim(this.elContent.value); + // work around chrome bug + if (content == YAHOO.bugzilla.instantSearch.elContent.getAttribute('placeholder')) { + return ''; + } else { + return content; + } + }, + + getProduct: function() { + var result = []; + var name = Dom.get('product').value; + result.push(name); + if (products[name] && products[name].related) { + for (var i = 0, n = products[name].related.length; i < n; i++) { + result.push(products[name].related[i]); + } + } + return result; + } + +}; + |