Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 301328 Details for
Bug 426374
3.8.1: Ajax Optimizations for Bug Query Pages
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Patch to optimize query.cgi using ajax to update component/version/milestone list
query.patch (text/plain), 32.63 KB, created by
David Lawrence
on 2008-04-04 19:36:19 UTC
(
hide
)
Description:
Patch to optimize query.cgi using ajax to update component/version/milestone list
Filename:
MIME Type:
Creator:
David Lawrence
Created:
2008-04-04 19:36:19 UTC
Size:
32.63 KB
patch
obsolete
>Index: query.cgi >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/query.cgi,v >retrieving revision 1.6 >diff -u -r1.6 query.cgi >--- query.cgi 27 Mar 2008 15:06:06 -0000 1.6 >+++ query.cgi 4 Apr 2008 19:30:26 -0000 >@@ -197,6 +197,10 @@ > my %milestones; > > foreach my $product (@selectable_products) { >+ # REDHAT EXTENSION START 426374 >+ # Skip product if not in the list of selected products >+ # REDHAT EXTENSION END 426374 >+ next if $cgi->param('product') and not grep ($_ eq $product->name, $cgi->param('product')); > $components{$_->name} = 1 foreach (@{$product->components}); > $versions{$_->name} = 1 foreach (@{$product->versions}); > $milestones{$_->name} = 1 foreach (@{$product->milestones}); >Index: js/rpc-min.js >=================================================================== >RCS file: js/rpc-min.js >diff -N js/rpc-min.js >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ js/rpc-min.js 4 Apr 2008 19:30:27 -0000 >@@ -0,0 +1,159 @@ >+var rpc={version:"0.8.0.2",requestCount:0};rpc.ServiceProxy=function(serviceURL,options){this.__serviceURL=serviceURL;this.__isCrossSite=false;var urlParts=this.__serviceURL.match(/^(\w+:)\/\/([^\/]+?)(?::(\d+))?(?:$|\/)/);if(urlParts){this.__isCrossSite=(location.protocol!=urlParts[1]||document.domain!=urlParts[2]||location.port!=(urlParts[3]||""));} >+var providedMethodList;this.__isAsynchronous=true;this.__isResponseSanitized=true;this.__authUsername=null;this.__authPassword=null;this.__callbackParamName='JSON-response-callback';this.__protocol='JSON-RPC';this.__dateEncoding='ISO8601';this.__decodeISO8601=true;if(options instanceof Object){if(options.asynchronous!==undefined){this.__isAsynchronous=!!options.asynchronous;if(!this.__isAsynchronous&&this.__isCrossSite) >+throw Error("It is not possible to establish a synchronous connection to a cross-site RPC service.");} >+if(options.sanitize!=undefined) >+this.__isResponseSanitized=!!options.sanitize;if(options.user!=undefined) >+this.__authUsername=options.user;if(options.password!=undefined) >+this.__authPassword=options.password;if(options.callbackParamName!=undefined) >+this.__callbackParamName=options.callbackParamName;if(String(options.protocol).toUpperCase()=='XML-RPC') >+this.__protocol='XML-RPC';if(options.dateEncoding!=undefined) >+this.__dateEncoding=options.dateEncoding;if(options.decodeISO8601!=undefined) >+this.__decodeISO8601=!!options.decodeISO8601;providedMethodList=options.methods;} >+if(this.__isCrossSite){if(this.__isResponseSanitized){throw Error("You are attempting to access a service on another site, and the JSON data returned "+ >+"by cross-site requests cannot be sanitized. You must therefore explicitly set the "+ >+"'sanitize' option to false (it is true by default) in order to proceed with making "+ >+"potentially insecure cross-site rpc calls.");} >+else if(this.__protocol=='XML-RPC') >+throw Error("Unable to use the XML-RPC protocol to access services on other domains.");} >+if(this.__isCrossSite&&!providedMethodList) >+throw Error("You must manually supply the service's method names since auto-introspection is not permitted for cross-site services.");if(providedMethodList) >+this.__methodList=providedMethodList;else{var async=this.__isAsynchronous;this.__isAsynchronous=false;this.__methodList=this.__callMethod("system.listMethods",[]);this.__isAsynchronous=async;} >+this.__methodList.push('system.listMethods');this.__methodList.push('system.describe');for(var methodName,i=0;methodName=this.__methodList[i];i++){var methodObject=this;var propChain=methodName.split(/\./);for(var j=0;j+1<propChain.length;j++){if(!methodObject[propChain[j]]) >+methodObject[propChain[j]]={};methodObject=methodObject[propChain[j]];} >+var wrapper=(function(instance,methodName){var call={instance:instance,methodName:methodName};return function(){if(call.instance.__isAsynchronous){if(arguments.length==1&&arguments[0]instanceof Object){call.instance.__callMethod(call.methodName,arguments[0].params,arguments[0].onSuccess,arguments[0].onException,arguments[0].onComplete);} >+else{call.instance.__callMethod(call.methodName,arguments[0],arguments[1],arguments[2],arguments[3]);} >+return undefined;} >+else return call.instance.__callMethod(call.methodName,rpc.toArray(arguments));};})(this,methodName);methodObject[propChain[propChain.length-1]]=wrapper;}};rpc.setAsynchronous=function(serviceProxy,isAsynchronous){if(!isAsynchronous&&serviceProxy.__isCrossSite) >+throw Error("It is not possible to establish a synchronous connection to a cross-site RPC service.");serviceProxy.__isAsynchronous=!!isAsynchronous;};rpc.ServiceProxy.prototype.__callMethod=function(methodName,params,successHandler,exceptionHandler,completeHandler){rpc.requestCount++;if(this.__isAsynchronous){if(successHandler&&typeof successHandler!='function') >+throw Error('The asynchronous onSuccess handler callback function you provided is invalid; the value you provided ('+successHandler.toString()+') is of type "'+typeof(successHandler)+'".');if(exceptionHandler&&typeof exceptionHandler!='function') >+throw Error('The asynchronous onException handler callback function you provided is invalid; the value you provided ('+exceptionHandler.toString()+') is of type "'+typeof(exceptionHandler)+'".');if(completeHandler&&typeof completeHandler!='function') >+throw Error('The asynchronous onComplete handler callback function you provided is invalid; the value you provided ('+completeHandler.toString()+') is of type "'+typeof(completeHandler)+'".');} >+try{if(this.__isAsynchronous||this.__isCrossSite){rpc.pendingRequests[String(rpc.requestCount)]={onSuccess:successHandler,onException:exceptionHandler,onComplete:completeHandler};} >+if(this.__isCrossSite){rpc.callbacks['r'+String(rpc.requestCount)]=(function(instance,id){var call={instance:instance,id:id};return function(response){if(response instanceof Object&&(response.result||response.error)){response.id=call.id;instance.__doCallback(response);} >+else{instance.__doCallback({id:call.id,result:response});}}})(this,rpc.requestCount);var script=document.createElement('script');script.setAttribute('type','text/javascript');var src=this.__serviceURL+ >+'/'+methodName+ >+'?'+this.__callbackParamName+'=rpc.callbacks.r'+(rpc.requestCount);if(params) >+src+='&'+rpc.toQueryString(params);script.setAttribute('src',src);script.setAttribute('id','rpc'+rpc.requestCount);var head=document.getElementsByTagName('head')[0];rpc.pendingRequests[rpc.requestCount].scriptElement=script;head.appendChild(script);return undefined;} >+else{if(params){if(!(params instanceof Object)||params instanceof Date) >+throw Error('When making asynchronous calls, the parameters for the method must be passed as an array (or a hash); the value you supplied ('+String(params)+') is of type "'+typeof(params)+'".');} >+var request,postData;if(this.__protocol=='XML-RPC'){if(!(params instanceof Array)) >+throw Error("Unable to pass associative arrays to XML-RPC services.");var xml=['<?xml version="1.0"?><methodCall><methodName>'+methodName+'</methodName>'];if(params){xml.push('<params>');for(var i=0;i<params.length;i++) >+xml.push('<param>'+this.__toXMLRPC(params[i])+'</param>');xml.push('</params>');} >+xml.push('</methodCall>');postData=xml.join('');} >+else{request={version:"1.1",method:methodName,id:rpc.requestCount};if(params) >+request.params=params;postData=this.__toJSON(request);} >+var xhr;if(window.XMLHttpRequest) >+xhr=new XMLHttpRequest();else if(window.ActiveXObject){try{xhr=new ActiveXObject('Msxml2.XMLHTTP');}catch(err){xhr=new ActiveXObject('Microsoft.XMLHTTP');}} >+xhr.open('POST',this.__serviceURL,this.__isAsynchronous,this.__authUsername,this.__authPassword);if(this.__protocol=='XML-RPC'){xhr.setRequestHeader('Content-Type','text/xml');xhr.setRequestHeader('Accept','text/xml');} >+else{xhr.setRequestHeader('Content-Type','application/json');xhr.setRequestHeader('Accept','application/json');} >+if(this.__isAsynchronous){xhr.send(postData);var instance=this;var requestInfo={id:rpc.requestCount};xhr.onreadystatechange=function(){if(xhr.readyState==4){if(instance.__protocol=='XML-RPC'){var response=instance.__getXMLRPCResponse(xhr,requestInfo.id);instance.__doCallback(response);} >+else{var response=instance.__evalJSON(xhr.responseText,instance.__isResponseSanitized);if(!response.id) >+response.id=requestInfo.id;instance.__doCallback(response);}}};return undefined;} >+else{xhr.send(postData);var response;if(this.__protocol=='XML-RPC') >+response=this.__getXMLRPCResponse(xhr,rpc.requestCount);else >+response=this.__evalJSON(xhr.responseText,this.__isResponseSanitized);if(response.error) >+throw Error('Unable to call "'+methodName+'". Server responsed with error (code '+response.error.code+'): '+response.error.message);this.__upgradeValuesFromJSON(response);return response.result;}}} >+catch(err){var isCaught=false;if(exceptionHandler) >+isCaught=exceptionHandler(err);if(completeHandler) >+completeHandler();if(!isCaught) >+throw err;}};rpc.pendingRequests={};rpc.callbacks={};rpc.ServiceProxy.prototype.__doCallback=function(response){if(typeof response!='object') >+throw Error('The server did not respond with a response object.');if(!response.id) >+throw Error('The server did not respond with the required response id for asynchronous calls.');if(!rpc.pendingRequests[response.id]) >+throw Error('Fatal error with RPC code: no ID "'+response.id+'" found in pendingRequests.');if(rpc.pendingRequests[response.id].scriptElement){var script=rpc.pendingRequests[response.id].scriptElement;script.parentNode.removeChild(script);} >+if(rpc.callbacks[response.id]) >+delete rpc.callbacks['r'+response.id];var uncaughtExceptions=[];if(response.error!==undefined){var err=new Error(response.error.message);err.code=response.error.code;if(rpc.pendingRequests[response.id].onException){try{if(!rpc.pendingRequests[response.id].onException(err)) >+uncaughtExceptions.push(err);} >+catch(err2){uncaughtExceptions.push(err);uncaughtExceptions.push(err2);}} >+else uncaughtExceptions.push(err);} >+else if(response.result!==undefined){this.__upgradeValuesFromJSON(response);if(rpc.pendingRequests[response.id].onSuccess){try{rpc.pendingRequests[response.id].onSuccess(response.result);} >+catch(err){if(rpc.pendingRequests[response.id].onException){try{if(!rpc.pendingRequests[response.id].onException(err)) >+uncaughtExceptions.push(err);} >+catch(err2){uncaughtExceptions.push(err);uncaughtExceptions.push(err2);}} >+else uncaughtExceptions.push(err);}}} >+try{if(rpc.pendingRequests[response.id].onComplete) >+rpc.pendingRequests[response.id].onComplete(response);} >+catch(err){if(rpc.pendingRequests[response.id].onException){try{if(!rpc.pendingRequests[response.id].onException(err)) >+uncaughtExceptions.push(err);} >+catch(err2){uncaughtExceptions.push(err);uncaughtExceptions.push(err2);}} >+else uncaughtExceptions.push(err);} >+delete rpc.pendingRequests[response.id];if(uncaughtExceptions.length){var code;var message='There '+(uncaughtExceptions.length==1?'was 1 uncaught exception':'were '+uncaughtExceptions.length+' uncaught exceptions')+': ';for(var i=0;i<uncaughtExceptions.length;i++){if(i) >+message+="; ";message+=uncaughtExceptions[i].message;if(uncaughtExceptions[i].code) >+code=uncaughtExceptions[i].code;} >+var err=new Error(message);err.code=code;throw err;}};rpc.ServiceProxy.prototype.__toJSON=function(value){switch(typeof value){case'number':return isFinite(value)?value.toString():'null';case'boolean':return value.toString();case'string':var specialChars={"\b":'\\b',"\t":'\\t',"\n":'\\n',"\f":'\\f',"\r":'\\r','"':'\\"',"\\":'\\\\',"/":'\/'};return'"'+value.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=specialChars[b];if(c) >+return c;c=b.charCodeAt();return'\\u00'+rpc.zeroPad(c.toString(16));})+'"';case'object':if(value===null) >+return'null';else if(value instanceof Array){var json=['['];for(var i=0;i<value.length;i++){if(i) >+json.push(',');json.push(this.__toJSON(value[i]));} >+json.push(']');return json.join('');} >+else if(value instanceof Date){switch(this.__dateEncoding){case'classHinting':return'{"__jsonclass__":["Date",['+value.valueOf()+']]}';case'@timestamp@':case'@ticks@':return'"@'+value.valueOf()+'@"';case'ASP.NET':return'"\\/Date('+value.valueOf()+')\\/"';default:return'"'+rpc.dateToISO8601(value)+'"';}} >+else if(value instanceof Number||value instanceof String||value instanceof Boolean) >+return this.__toJSON(value.valueOf());else{var useHasOwn={}.hasOwnProperty?true:false;var json=['{'];for(var key in value){if(!useHasOwn||value.hasOwnProperty(key)){if(json.length>1) >+json.push(',');json.push(this.__toJSON(key)+':'+this.__toJSON(value[key]));}} >+json.push('}');return json.join('');} >+} >+throw new TypeError('Unable to convert the value of type "'+typeof(value)+'" to JSON.');};rpc.isJSON=function(string){var testStr=string.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"/g,'');return(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(testStr);};rpc.ServiceProxy.prototype.__evalJSON=function(json,sanitize){json=json.replace(/^\/\*-secure-([\s\S]*)\*\/\s*$/,"$1");var err;try{if(!sanitize||rpc.isJSON(json)) >+return eval('('+json+')');} >+catch(e){err=e;} >+throw new SyntaxError('Badly formed JSON string: '+json+" ... "+(err?err.message:''));};rpc.ServiceProxy.prototype.__upgradeValuesFromJSON=function(obj){var matches,useHasOwn={}.hasOwnProperty?true:false;for(var key in obj){if(!useHasOwn||obj.hasOwnProperty(key)){if(typeof obj[key]=='string'){if(this.__decodeISO8601&&(matches=obj[key].match(/^(?:(\d\d\d\d)-(\d\d)(?:-(\d\d)(?:T(\d\d)(?::(\d\d)(?::(\d\d)(?:\.(\d+))?)?)?)?)?)$/))){obj[key]=new Date(0);if(matches[1])obj[key].setUTCFullYear(parseInt(matches[1]));if(matches[2])obj[key].setUTCMonth(parseInt(matches[2]-1));if(matches[3])obj[key].setUTCDate(parseInt(matches[3]));if(matches[4])obj[key].setUTCHours(parseInt(matches[4]));if(matches[5])obj[key].setUTCMinutes(parseInt(matches[5]));if(matches[6])obj[key].setUTCMilliseconds(parseInt(matches[6]));} >+//@timestamp@ / @ticks@ else if(matches=obj[key].match(/^@(\d+)@$/)){obj[key]=new Date(parseInt(matches[1]))} >+else if(matches=obj[key].match(/^\/Date\((\d+)\)\/$/)){obj[key]=new Date(parseInt(matches[1]))}} >+else if(obj[key]instanceof Object){if(obj[key].__jsonclass__ instanceof Array){if(obj[key].__jsonclass__[0]=='Date'){if(obj[key].__jsonclass__[1]instanceof Array&&obj[key].__jsonclass__[1][0]) >+obj[key]=new Date(obj[key].__jsonclass__[1][0]);else >+obj[key]=new Date();}} >+else this.__upgradeValuesFromJSON(obj[key]);}}}};rpc.ServiceProxy.prototype.__toXMLRPC=function(value){var xml=['<value>'];switch(typeof value){case'number':if(!isFinite(value)) >+xml.push('<nil/>');else if(parseInt(value)==Math.ceil(value)){xml.push('<int>');xml.push(value.toString());xml.push('</int>');} >+else{xml.push('<double>');xml.push(value.toString());xml.push('</double>');} >+break;case'boolean':xml.push('<boolean>');xml.push(value?'1':'0');xml.push('</boolean>');break;case'string':xml.push('<string>');xml.push(value.replace(/[<>&]/,function(ch){}));xml.push('</string>');break;case'object':if(value===null) >+xml.push('<nil/>');else if(value instanceof Array){xml.push('<array><data>');for(var i=0;i<value.length;i++) >+xml.push(this.__toXMLRPC(value[i]));xml.push('</data></array>');} >+else if(value instanceof Date){xml.push('<dateTime.iso8601>'+rpc.dateToISO8601(value)+'</dateTime.iso8601>');} >+else if(value instanceof Number||value instanceof String||value instanceof Boolean) >+return rpc.dateToISO8601(value.valueOf());else{xml.push('<struct>');var useHasOwn={}.hasOwnProperty?true:false;for(var key in value){if(!useHasOwn||value.hasOwnProperty(key)){xml.push('<member>');xml.push('<name>'+key+'</name>');xml.push(this.__toXMLRPC(value[key]));xml.push('</member>');}} >+xml.push('</struct>');} >+break;default:throw new TypeError('Unable to convert the value of type "'+typeof(value)+'" to XML-RPC.');} >+xml.push('</value>');return xml.join('');};rpc.ServiceProxy.prototype.__parseXMLRPC=function(valueEl){if(valueEl.childNodes.length==1&&valueEl.childNodes.item(0).nodeType==3) >+{return valueEl.childNodes.item(0).nodeValue;} >+for(var i=0;i<valueEl.childNodes.length;i++){if(valueEl.childNodes.item(i).nodeType==1){var typeEL=valueEl.childNodes.item(i);switch(typeEL.nodeName.toLowerCase()){case'i4':case'int':var intVal=parseInt(typeEL.firstChild.nodeValue);if(isNaN(intVal)) >+throw Error("XML-RPC Parse Error: The value provided as an integer '"+typeEL.firstChild.nodeValue+"' is invalid.");return intVal;case'double':var floatVal=parseFloat(typeEL.firstChild.nodeValue);if(isNaN(floatVal)) >+throw Error("XML-RPC Parse Error: The value provided as a double '"+typeEL.firstChild.nodeValue+"' is invalid.");return floatVal;case'boolean':if(typeEL.firstChild.nodeValue!='0'&&typeEL.firstChild.nodeValue!='1') >+throw Error("XML-RPC Parse Error: The value provided as a boolean '"+typeEL.firstChild.nodeValue+"' is invalid.");return Boolean(parseInt(typeEL.firstChild.nodeValue));case'string':if(!typeEL.firstChild) >+return"";return typeEL.firstChild.nodeValue;case'datetime.iso8601':var matches,date=new Date(0);if(matches=typeEL.firstChild.nodeValue.match(/^(?:(\d\d\d\d)-(\d\d)(?:-(\d\d)(?:T(\d\d)(?::(\d\d)(?::(\d\d)(?:\.(\d+))?)?)?)?)?)$/)){if(matches[1])date.setUTCFullYear(parseInt(matches[1]));if(matches[2])date.setUTCMonth(parseInt(matches[2]-1));if(matches[3])date.setUTCDate(parseInt(matches[3]));if(matches[4])date.setUTCHours(parseInt(matches[4]));if(matches[5])date.setUTCMinutes(parseInt(matches[5]));if(matches[6])date.setUTCMilliseconds(parseInt(matches[6]));return date;} >+throw Error("XML-RPC Parse Error: The provided value does not match ISO8601.");case'base64':throw Error("Not able to parse base64 data yet.");case'nil':return null;case'struct':var obj={};for(var memberEl,j=0;memberEl=typeEL.childNodes.item(j);j++){if(memberEl.nodeType==1&&memberEl.nodeName=='member'){var name='';valueEl=null;for(var child,k=0;child=memberEl.childNodes.item(k);k++){if(child.nodeType==1){if(child.nodeName=='name') >+name=child.firstChild.nodeValue;else if(child.nodeName=='value') >+valueEl=child;}} >+if(name&&valueEl) >+obj[name]=this.__parseXMLRPC(valueEl);}} >+return obj;case'array':var arr=[];var dataEl=typeEL.firstChild;while(dataEl&&(dataEl.nodeType!=1||dataEl.nodeName!='data')) >+dataEl=dataEl.nextSibling;if(!dataEl) >+new Error("XML-RPC Parse Error: Expected 'data' element as sole child element of 'array'.");valueEl=dataEl.firstChild;while(valueEl){if(valueEl.nodeType==1){if(valueEl.nodeName=='value') >+arr.push(this.__parseXMLRPC(valueEl));else >+throw Error("XML-RPC Parse Error: Illegal element child '"+valueEl.nodeName+"' of an array's 'data' element.");} >+valueEl=valueEl.nextSibling;} >+return arr;default:throw Error("XML-RPC Parse Error: Illegal element '"+typeEL.nodeName+"' child of the 'value' element.");}}} >+return'';} >+rpc.ServiceProxy.prototype.__getXMLRPCResponse=function(xhr,id){var response={};if(!xhr.responseXML) >+throw Error("Malformed XML document.");var doc=xhr.responseXML.documentElement;if(doc.nodeName!='methodResponse') >+throw Error("Invalid XML-RPC document.");var valueEl=doc.getElementsByTagName('value')[0];if(valueEl.parentNode.nodeName=='param'&&valueEl.parentNode.parentNode.nodeName=='params') >+{response.result=this.__parseXMLRPC(valueEl);} >+else if(valueEl.parentNode.nodeName=='fault'){var fault=this.__parseXMLRPC(valueEl);response.error={code:fault.faultCode,message:fault.faultString};} >+else throw Error("Invalid XML-RPC document.");if(!response.result&&!response.error) >+throw Error("Malformed XML-RPC methodResponse document.");response.id=id;return response;};rpc.toQueryString=function(params){if(!(params instanceof Object||params instanceof Array)||params instanceof Date) >+throw Error('You must supply either an array or object type to convert into a query string. You supplied: '+params.constructor);var str='';var useHasOwn={}.hasOwnProperty?true:false;for(var key in params){if(useHasOwn&¶ms.hasOwnProperty(key)){if(params[key]instanceof Array){for(var i=0;i<params[key].length;i++){if(str) >+str+='&';str+=encodeURIComponent(key)+"=";if(params[key][i]instanceof Date) >+str+=encodeURIComponent(rpc.dateToISO8601(params[key][i]));else if(params[key][i]instanceof Object) >+throw Error('Unable to pass nested arrays nor objects as parameters while in making a cross-site request. The object in question has this constructor: '+params[key][i].constructor);else str+=encodeURIComponent(String(params[key][i]));}} >+else{if(str) >+str+='&';str+=encodeURIComponent(key)+"=";if(params[key]instanceof Date) >+str+=encodeURIComponent(rpc.dateToISO8601(params[key]));else if(params[key]instanceof Object) >+throw Error('Unable to pass objects as parameters while in making a cross-site request. The object in question has this constructor: '+params[key].constructor);else str+=encodeURIComponent(String(params[key]));}}} >+return str;};rpc.toArray=function(value){if(value instanceof Array) >+return value;var array=[];for(var i=0;i<value.length;i++) >+array.push(value[i]);return array;};rpc.dateToISO8601=function(date){return date.getUTCFullYear()+'-'+ >+rpc.zeroPad(date.getUTCMonth()+1)+'-'+ >+rpc.zeroPad(date.getUTCDate())+'T'+ >+rpc.zeroPad(date.getUTCHours())+':'+ >+rpc.zeroPad(date.getUTCMinutes())+':'+ >+rpc.zeroPad(date.getUTCSeconds())+'.'+ >+rpc.zeroPad(date.getUTCMilliseconds(),3);};rpc.zeroPad=function(value,width){if(!width) >+width=2;value=(value==undefined?'':String(value)) >+while(value.length<width) >+value='0'+value;return value;}; >Index: js/query.js >=================================================================== >RCS file: js/query.js >diff -N js/query.js >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ js/query.js 4 Apr 2008 19:30:27 -0000 >@@ -0,0 +1,70 @@ >+/* 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/ >+ * >+ * 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. >+ * >+ * The Initial Developer of the Original Code is Netscape Communications >+ * Corporation. Portions created by Netscape are >+ * Copyright (C) 1998 Netscape Communications Corporation. All >+ * Rights Reserved. >+ * >+ * Contributor(s): Christian Reis <kiko@async.com.br> >+ * David Lawrence <dkl@redhat.com> >+ */ >+ >+// Functions to update form select elements for the query.cgi page. >+ >+var savedSelects = []; >+savedSelects['product'] = []; >+savedSelects['component'] = []; >+savedSelects['version'] = []; >+savedSelects['target_milestone'] = []; >+ >+/** >+ * Update the query.cgi select fields with results from the xmlrpc requests >+ * >+ * @param None >+ * @return None >+ */ >+function updateQuerySelects() { >+ var products = findSelectedProducts(); >+ if (first_load && products.length == 0) { >+ first_load = false; >+ return true; >+ } >+ first_load = false; >+ var fields = ['component','version','target_milestone']; >+ for (var i = 0; i < fields.length; i++) { >+ var sel = document.getElementById(fields[i]); >+ savedSelects[fields[i]] = savedSelects[fields[i]].length == 0 ? get_selection(sel,0,1) : savedSelects[fields[i]]; >+ var sel = document.getElementById(fields[i]); >+ sel.disabled = true; >+ } >+ var callback = { >+ params: [products], >+ onSuccess:function(result) { >+ for (var i = 0; i < fields.length; i++) { >+ var list = result[i]; >+ var sel = document.getElementById(fields[i]); >+ bz_populateSelectFromArray(sel,list,0,1); >+ sel.disabled = false; >+ restoreSelection(sel, savedSelects[fields[i]]); >+ savedSelects[fields[i]] = new Array(); >+ } >+ } >+ } >+ var xmlrpc_params = { >+ methods: ['bugzilla.getProductDetails'], >+ protocol: 'XML-RPC' >+ }; >+ var xmlrpc_client = new rpc.ServiceProxy(server_url, xmlrpc_params); >+ xmlrpc_client.bugzilla.getProductDetails(callback); >+} >+ >Index: template/en/default/search/form.html.tmpl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/template/en/default/search/form.html.tmpl,v >retrieving revision 1.4 >diff -u -r1.4 form.html.tmpl >--- template/en/default/search/form.html.tmpl 17 Mar 2008 21:37:00 -0000 1.4 >+++ template/en/default/search/form.html.tmpl 4 Apr 2008 19:30:27 -0000 >@@ -26,80 +26,27 @@ > var last_sel = new Array(); [%# caches last selection %] > > [% IF Param('useclassification') %] >-var useclassification = true; >-var prods = new Array(); >-[% ELSE %] >-var useclassification = false; >-[% END %] >-var cpts = new Array(); >-var vers = new Array(); >-[% IF Param('usetargetmilestone') %] >-var tms = new Array(); >-[% END %] >+ var useclassification = true; >+ var prods = new Array(); > >-[%# Create an array of products, indexed by the classification #%] >- >-[% nclass = 0 %] >-[% FOREACH c = classification %] >- prods[[% nclass FILTER js %]] = [ >- [% sep = '' %] >- [%- FOREACH item = user.get_selectable_products(c.id) -%] >- [%- IF item.components.size -%] >- [%- sep FILTER js %]'[% item.name FILTER js %]' >- [%- sep = ',' -%] >- [%- END -%] >- [%- END -%] ]; >- [% nclass = nclass+1 %] >-[% END %] >+ [%# Create an array of products, indexed by the classification #%] > >-[%# Create three arrays of components, versions and target milestones, indexed >- # numerically according to the product they refer to. #%] >- >-[% n = 0 %] >-[% FOREACH p = product %] >- [% NEXT IF NOT p.components.size %] >- [% IF Param('useclassification') %] >- prods['[% p.name FILTER js %]'] = [% n %] >- [% END %] >- cpts[[% n %]] = [ >- [%- FOREACH item = p.components %]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; >- vers[[% n %]] = [ >- [%- FOREACH item = p.versions -%]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; >- [% IF Param('usetargetmilestone') %] >- tms[[% n %]] = [ >- [%- FOREACH item = p.milestones %]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; >+ [% nclass = 0 %] >+ [% FOREACH c = classification %] >+ prods[[% nclass FILTER js %]] = [ >+ [% sep = '' %] >+ [%- FOREACH item = user.get_selectable_products(c.id) -%] >+ [%- IF item.components.size -%] >+ [%- sep FILTER js %]'[% item.name FILTER js %]' >+ [%- sep = ',' -%] >+ [%- END -%] >+ [%- END -%] ]; >+ [% nclass = nclass+1 %] > [% END %] >- [% n = n+1 %] >+ > [% END %] > >-/* >- * doOnSelectProduct determines which selection should get updated >- * >- * - selectmode = 0 - init >- * selectmode = 1 - classification selected >- * selectmode = 2 - product selected >- * >- * globals: >- * queryform - string holding the name of the selection form >- */ >-function doOnSelectProduct(selectmode) { >- var f = document.forms[queryform]; >- var milestone = (typeof(f.target_milestone) == "undefined" ? >- null : f.target_milestone); >- if (selectmode == 0) { >- // If there is no classification selected, give us a chance to fill >- // the select fields with values from the possibly selected product. >- if (useclassification && f.classification.selectedIndex > -1) { >- selectClassification(f.classification, f.product, f.component, f.version, milestone); >- } else { >- selectProduct(f.product, f.component, f.version, milestone, null); >- } >- } else if (selectmode == 1) { >- selectClassification(f.classification, f.product, f.component, f.version, milestone); >- } else { >- selectProduct(f.product, f.component, f.version, milestone, null); >- } >-} >+var f = document.forms[queryform]; > > </script> > >@@ -169,7 +116,7 @@ > <tr valign="top"> > <td align="left"> > <select name="classification" multiple="multiple" size="5" id="classification" >- onchange="doOnSelectProduct(1);"> >+ onchange="selectClassification(f.classification, f.product);"> > [% FOREACH cat = classification %] > <option value="[% cat.name FILTER html %]" > [% " selected" IF lsearch(default.classification, cat.name) != -1 %]> >@@ -193,7 +140,7 @@ > [%# Can't use the select block here because of the onChange %] > <td align="left"> > <select name="product" multiple="multiple" size="5" id="product" >- onchange="doOnSelectProduct(2);"> >+ onchange="updateQuerySelects();"> > [% FOREACH p = product %] > [% IF p.components.size %] > <option value="[% p.name FILTER html %]" >Index: template/en/default/search/search-advanced.html.tmpl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/template/en/default/search/search-advanced.html.tmpl,v >retrieving revision 1.1.1.1 >diff -u -r1.1.1.1 search-advanced.html.tmpl >--- template/en/default/search/search-advanced.html.tmpl 19 Nov 2007 22:11:21 -0000 1.1.1.1 >+++ template/en/default/search/search-advanced.html.tmpl 4 Apr 2008 19:30:27 -0000 >@@ -36,9 +36,9 @@ > > [% PROCESS global/header.html.tmpl > title = "Search for $terms.bugs" >- onload = "doOnSelectProduct(0); enableHelp();" >+ onload = "enableHelp();" > javascript = js_data >- javascript_urls = [ "js/productform.js" "js/util.js" "js/help.js" ] >+ javascript_urls = [ "js/productform.js", "js/util.js" "js/help.js", "js/rpc-min.js", "js/query.js" ] > style_urls = [ "skins/standard/help.css" ] > doc_section = "query.html" > style = "dl.bug_changes dt { >@@ -61,6 +61,12 @@ > else > document.write("<p>Help initialization failed, no help available.<\/p>"); > [% END %] >+ >+ // REDHAT EXTENSION 426374 >+ // Server URL is set here since we cannot access Param('sslbase') >+ // in the js/ files. >+ var server_url = "[% Param('sslbase') %]xmlrpc.cgi"; >+ > // --> > </script> > >@@ -76,7 +82,6 @@ > > </form> > >- > [% END %] > > [% PROCESS global/footer.html.tmpl %] >Index: extensions/compat_xmlrpc/code/webservice.pl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/extensions/compat_xmlrpc/code/webservice.pl,v >retrieving revision 1.22 >diff -u -r1.22 webservice.pl >--- extensions/compat_xmlrpc/code/webservice.pl 2 Apr 2008 00:46:28 -0000 1.22 >+++ extensions/compat_xmlrpc/code/webservice.pl 4 Apr 2008 19:30:30 -0000 >@@ -2962,38 +2962,54 @@ > # in the given product, the second list are the valid versions for the given > # product. > sub getProductDetails { >- my ($self, $product, $username, $password ) = @_; >- >- $product || ThrowCodeError('param_required', { param => 'product' }); >+ my ($self, $product_ref, $username, $password ) = @_; >+ my @components = (); >+ my @versions = (); >+ my @milestones = (); >+ my @products = (); > > # Try to login if $username and $password provided. >- xmlrpc_client_login($username, $password, LOGIN_REQUIRED); >+ xmlrpc_client_login($username, $password); >+ >+ @products = ref($product_ref) ? @$product_ref : ($product_ref); >+ >+ if (!@products) { >+ @products = @{Bugzilla->user->get_selectable_products()}; >+ } >+ >+ $logger->debug("Starting: " . join(", ", @products) . ", $username"); >+ >+ foreach my $product (@products) { >+ my $product_obj = Bugzilla::Product->check($product) >+ if Bugzilla->user->can_see_product($product, THROW_ERROR); > >- $logger->debug("Starting: $product, $username"); > >- my $product_obj = Bugzilla::Product->check($product) >- if Bugzilla->user->can_enter_product($product, THROW_ERROR); >- >- my @components = $product_obj->components(); >- my @versions = $product_obj->versions(); >- >- my @comps; >- >- foreach my $item (@components){ >- foreach my $c (@$item){ >- push (@comps, $c->{name}); >- } >- } >- >- my @vers; >- >- foreach my $item (@versions){ >- foreach my $v (@$item){ >- push (@vers, $v->{value}); >- } >- } >- >- return [\@comps, \@vers]; >+ my @comps = $product_obj->components(); >+ my @vers = $product_obj->versions(); >+ my @miles = $product_obj->milestones(); >+ >+ foreach my $item (sort { $a cmp $b } @comps){ >+ foreach my $c (@$item){ >+ push (@components, type('string')->value($c->{name})); >+ } >+ } >+ >+ foreach my $item (sort { vers_cmp (lc($a), lc($b)) } @vers){ >+ foreach my $v (@$item){ >+ push (@versions, type('string')->value($v->{value})); >+ } >+ } >+ >+ if (Bugzilla->params->{'usetargetmilestone'}) { >+ foreach my $item (sort { $a cmp $b } @miles){ >+ foreach my $m (@$item){ >+ push (@milestones, type('string')->value($m->{value})); >+ } >+ } >+ } >+ } >+ >+ return [\@components, \@versions, \@milestones]; > } > > # helper sub to turn a product name into an id, checking that it exists
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 426374
:
301328
|
302696