Commit 0b4ee129 authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 376673: Add a simple version of the bug entry form (enter_bug.cgi)

Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=pyrzak, r=LpSolit, a=LpSolit
parent 9598c540
...@@ -16,153 +16,93 @@ ...@@ -16,153 +16,93 @@
* Rights Reserved. * Rights Reserved.
* *
* Contributor(s): Dennis Melentyev <dennis.melentyev@infopulse.com.ua> * Contributor(s): Dennis Melentyev <dennis.melentyev@infopulse.com.ua>
* Max Kanat-Alexander <mkanat@bugzilla.org>
*/ */
/* This file provides JavaScript functions to be included once one wish /* This file provides JavaScript functions to be included when one wishes
* to add a hide/reveal/collapse per-class functionality * to show/hide certain UI elements, and have the state of them being
* * shown/hidden stored in a cookie.
* *
* This file contains hide/reveal API for customizable page views * TUI stands for Tweak UI.
* TUI stands for Tweak UI. *
* * Requires js/util.js and the YUI Dom and Cookie libraries.
* See bug 262592 for usage examples. *
* * See template/en/default/bug/create/create.html.tmpl for a usage example.
* Note: this interface is experimental and under development. */
* We may and probably will make breaking changes to it in the future.
*/
var TUIClasses = new Array;
var TUICookiesEnabled = -1;
// Internal function to demangle cookies var TUI_HIDDEN_CLASS = 'bz_tui_hidden';
function TUI_demangle(value) { var TUI_COOKIE_NAME = 'TUI';
var pair;
var pairs = value.split(",");
for (i = 0; i < pairs.length; i++) {
pair = pairs[i].split(":");
if (pair[0] != null && pair[1] != null)
TUIClasses[pair[0]] = pair[1];
}
}
/* TUI_tweak: Function to redraw whole document. var TUI_alternates = new Array();
* Also, initialize TUIClasses array with defaults, then override it
* with values from cookie
*/
function TUI_tweak( cookiesuffix, classes ) { /**
var dc = document.cookie; * Hides a particular class of elements if they are shown,
var begin = -1; * or shows them if they are hidden. Then it stores whether that
var end = 0; * class is now hidden or shown.
*
* @param className The name of the CSS class to hide.
*/
function TUI_toggle_class(className) {
var elements = YAHOO.util.Dom.getElementsByClassName(className);
for (var i = 0; i < elements.length; i++) {
bz_toggleClass(elements[i], TUI_HIDDEN_CLASS);
}
_TUI_save_class_state(elements, className);
_TUI_toggle_control_link(className);
}
// Register classes and their defaults
TUI_demangle(classes);
if (TUICookiesEnabled > 0) { /**
// If cookies enabled, process them * Specifies that a certain class of items should be hidden by default,
TUI_demangle(TUI_getCookie(cookiesuffix)); * if the user doesn't have a TUI cookie.
} *
else if (TUICookiesEnabled == -1) { * @param className The class to hide by default.
// If cookies availability not checked yet since browser does */
// not has navigator.cookieEnabled property, let's check it manualy function TUI_hide_default(className) {
var cookie = TUI_getCookie(cookiesuffix); YAHOO.util.Event.onDOMReady(function () {
if (cookie.length == 0) if (!YAHOO.util.Cookie.getSub('TUI', className)) {
{ TUI_toggle_class(className);
TUI_setCookie(cookiesuffix);
// Cookies are definitely disabled for JS.
if (TUI_getCookie(cookiesuffix).length == 0)
TUICookiesEnabled = 0;
else
TUICookiesEnabled = 1;
}
else {
// Have cookie set, pretend to be able to reset them later on
TUI_demangle(cookie);
TUICookiesEnabled = 1;
}
}
if (TUICookiesEnabled > 0) {
var els = document.getElementsByTagName('*');
for (i = 0; i < els.length; i++) {
if (null != TUIClasses[els[i].className]) {
TUI_apply(els[i], TUIClasses[els[i].className]);
} }
} });
} }
return;
}
// TUI_apply: Function to draw certain element. function _TUI_toggle_control_link(className) {
// Receives element itself and style value: hide, reveal or collapse var link = document.getElementById(className + "_controller");
var original_text = link.innerHTML;
link.innerHTML = TUI_alternates[className];
TUI_alternates[className] = original_text;
}
function TUI_apply(element, value) { function _TUI_save_class_state(elements, aClass) {
if (TUICookiesEnabled > 0 && element != null) { // We just check the first element to see if it's hidden or not, and
switch (value) // consider that all elements are the same.
{ if (YAHOO.util.Dom.hasClass(elements[0], TUI_HIDDEN_CLASS)) {
case 'hide': _TUI_store(aClass, 0);
element.style.visibility="hidden"; }
break; else {
case 'collapse': _TUI_store(aClass, 1);
element.style.visibility="hidden";
element.style.display="none";
break;
case 'reveal': // Shown item must expand
default: // The default is to show & expand
element.style.visibility="visible";
element.style.display="";
break;
}
} }
} }
// TUI_change: Function to process class. function _TUI_store(aClass, state) {
// Usualy called from onclick event of button YAHOO.util.Cookie.setSub(TUI_COOKIE_NAME, aClass, state,
{
expires: new Date('January 1, 2038'),
path: BUGZILLA.param.cookie_path
});
}
function TUI_change(cookiesuffix, clsname, action) { function _TUI_restore() {
if (TUICookiesEnabled > 0) { var classes = YAHOO.util.Cookie.getSubs(TUI_COOKIE_NAME);
var els, i; for (item in classes) {
els = document.getElementsByTagName('*'); if (classes[item] == 0) {
for (i=0; i<els.length; i++) { var elements = YAHOO.util.Dom.getElementsByClassName(item);
if (els[i].className.match(clsname)) { for (var i = 0; i < elements.length; i++) {
TUI_apply(els[i], action); YAHOO.util.Dom.addClass(elements[i], 'bz_tui_hidden');
}
_TUI_toggle_control_link(item);
} }
}
TUIClasses[clsname]=action;
TUI_setCookie(cookiesuffix);
} }
} }
// TUI_setCookie: Function to set TUI cookie.
// Used internally
function TUI_setCookie(cookiesuffix) { YAHOO.util.Event.onDOMReady(_TUI_restore);
var cookieval = "";
var expireOn = new Date();
expireOn.setYear(expireOn.getFullYear() + 25);
for (clsname in TUIClasses) {
if (cookieval.length > 0)
cookieval += ",";
cookieval += clsname+":"+TUIClasses[clsname];
}
document.cookie="Bugzilla_TUI_"+cookiesuffix+"="+cookieval+"; expires="+expireOn.toString();
}
// TUI_getCookie: Function to get TUI cookie.
// Used internally
function TUI_getCookie(cookiesuffix) {
var dc = document.cookie;
var begin, end;
var cookiePrefix = "Bugzilla_TUI_"+cookiesuffix+"=";
begin = dc.indexOf(cookiePrefix, end);
if (begin != -1) {
begin += cookiePrefix.length;
end = dc.indexOf(";", begin);
if (end == -1) {
end = dc.length;
}
return unescape(dc.substring(begin, end));
}
return "";
}
...@@ -253,3 +253,21 @@ function bz_fireEvent(anElement, anEvent) { ...@@ -253,3 +253,21 @@ function bz_fireEvent(anElement, anEvent) {
evt.initEvent(anEvent, true, true); // event type, bubbling, cancelable evt.initEvent(anEvent, true, true); // event type, bubbling, cancelable
return !anElement.dispatchEvent(evt); return !anElement.dispatchEvent(evt);
} }
/**
* Adds a CSS class to an element if it doesn't have it. Removes the
* CSS class from the element if the element does have the class.
*
* Requires YUI's Dom library.
*
* @param anElement The element to toggle the class on
* @param aClass The name of the CSS class to toggle.
*/
function bz_toggleClass(anElement, aClass) {
if (YAHOO.util.Dom.hasClass(anElement, aClass)) {
YAHOO.util.Dom.removeClass(anElement, aClass);
}
else {
YAHOO.util.Dom.addClass(anElement, aClass);
}
}
/*
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.6.0
*/
YAHOO.namespace("util");YAHOO.util.Cookie={_createCookieString:function(B,D,C,A){var F=YAHOO.lang;var E=encodeURIComponent(B)+"="+(C?encodeURIComponent(D):D);if(F.isObject(A)){if(A.expires instanceof Date){E+="; expires="+A.expires.toGMTString();}if(F.isString(A.path)&&A.path!=""){E+="; path="+A.path;}if(F.isString(A.domain)&&A.domain!=""){E+="; domain="+A.domain;}if(A.secure===true){E+="; secure";}}return E;},_createCookieHashString:function(B){var D=YAHOO.lang;if(!D.isObject(B)){throw new TypeError("Cookie._createCookieHashString(): Argument must be an object.");}var C=new Array();for(var A in B){if(D.hasOwnProperty(B,A)&&!D.isFunction(B[A])&&!D.isUndefined(B[A])){C.push(encodeURIComponent(A)+"="+encodeURIComponent(String(B[A])));}}return C.join("&");},_parseCookieHash:function(E){var D=E.split("&"),F=null,C=new Object();if(E.length>0){for(var B=0,A=D.length;B<A;B++){F=D[B].split("=");C[decodeURIComponent(F[0])]=decodeURIComponent(F[1]);}}return C;},_parseCookieString:function(I,A){var J=new Object();if(YAHOO.lang.isString(I)&&I.length>0){var B=(A===false?function(K){return K;}:decodeURIComponent);if(/[^=]+=[^=;]?(?:; [^=]+=[^=]?)?/.test(I)){var G=I.split(/;\s/g);var H=null;var C=null;var E=null;for(var D=0,F=G.length;D<F;D++){E=G[D].match(/([^=]+)=/i);if(E instanceof Array){H=decodeURIComponent(E[1]);C=B(G[D].substring(E[1].length+1));}else{H=decodeURIComponent(G[D]);C=H;}J[H]=C;}}}return J;},get:function(A,B){var D=YAHOO.lang;var C=this._parseCookieString(document.cookie);if(!D.isString(A)||A===""){throw new TypeError("Cookie.get(): Cookie name must be a non-empty string.");}if(D.isUndefined(C[A])){return null;}if(!D.isFunction(B)){return C[A];}else{return B(C[A]);}},getSub:function(A,C,B){var E=YAHOO.lang;var D=this.getSubs(A);if(D!==null){if(!E.isString(C)||C===""){throw new TypeError("Cookie.getSub(): Subcookie name must be a non-empty string.");}if(E.isUndefined(D[C])){return null;}if(!E.isFunction(B)){return D[C];}else{return B(D[C]);}}else{return null;}},getSubs:function(A){if(!YAHOO.lang.isString(A)||A===""){throw new TypeError("Cookie.getSubs(): Cookie name must be a non-empty string.");}var B=this._parseCookieString(document.cookie,false);if(YAHOO.lang.isString(B[A])){return this._parseCookieHash(B[A]);}return null;},remove:function(B,A){if(!YAHOO.lang.isString(B)||B===""){throw new TypeError("Cookie.remove(): Cookie name must be a non-empty string.");}A=A||{};A.expires=new Date(0);return this.set(B,"",A);},removeSub:function(B,D,A){if(!YAHOO.lang.isString(B)||B===""){throw new TypeError("Cookie.removeSub(): Cookie name must be a non-empty string.");}if(!YAHOO.lang.isString(D)||D===""){throw new TypeError("Cookie.removeSub(): Subcookie name must be a non-empty string.");}var C=this.getSubs(B);if(YAHOO.lang.isObject(C)&&YAHOO.lang.hasOwnProperty(C,D)){delete C[D];return this.setSubs(B,C,A);}else{return"";}},set:function(B,C,A){var E=YAHOO.lang;if(!E.isString(B)){throw new TypeError("Cookie.set(): Cookie name must be a string.");}if(E.isUndefined(C)){throw new TypeError("Cookie.set(): Value cannot be undefined.");}var D=this._createCookieString(B,C,true,A);document.cookie=D;return D;},setSub:function(B,D,C,A){var F=YAHOO.lang;if(!F.isString(B)||B===""){throw new TypeError("Cookie.setSub(): Cookie name must be a non-empty string.");}if(!F.isString(D)||D===""){throw new TypeError("Cookie.setSub(): Subcookie name must be a non-empty string.");}if(F.isUndefined(C)){throw new TypeError("Cookie.setSub(): Subcookie value cannot be undefined.");}var E=this.getSubs(B);if(!F.isObject(E)){E=new Object();}E[D]=C;return this.setSubs(B,E,A);},setSubs:function(B,C,A){var E=YAHOO.lang;if(!E.isString(B)){throw new TypeError("Cookie.setSubs(): Cookie name must be a string.");}if(!E.isObject(C)){throw new TypeError("Cookie.setSubs(): Cookie value must be an object.");}var D=this._createCookieString(B,this._createCookieHashString(C),false,A);document.cookie=D;return D;}};YAHOO.register("cookie",YAHOO.util.Cookie,{version:"2.6.0",build:"1321"});
\ No newline at end of file
...@@ -215,6 +215,11 @@ ...@@ -215,6 +215,11 @@
} }
/* generic (end) */ /* generic (end) */
/* Links that control whether or not something is visible. */
a.controller {
font-size: 115%;
}
div#docslinks { div#docslinks {
float: right; float: right;
border: 1px solid black; border: 1px solid black;
...@@ -306,7 +311,7 @@ div#docslinks { ...@@ -306,7 +311,7 @@ div#docslinks {
/** End Comments **/ /** End Comments **/
.bz_default_hidden { .bz_default_hidden, .bz_tui_hidden {
display: none; display: none;
} }
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
</td> </td>
</tr> </tr>
[% IF Param("maxlocalattachment") %] [% IF Param("maxlocalattachment") %]
<tr> <tr class="expert_fields">
<th>BigFile:</th> <th>BigFile:</th>
<td> <td>
<input type="checkbox" id="bigfile" <input type="checkbox" id="bigfile"
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
</tr> </tr>
[% END %] [% END %]
[% IF Param("allow_attach_url") %] [% IF Param("allow_attach_url") %]
<tr> <tr class="expert_fields">
<th><label for="attachurl">AttachURL</label>:</th> <th><label for="attachurl">AttachURL</label>:</th>
<td> <td>
<em>URL to be attached instead.</em><br> <em>URL to be attached instead.</em><br>
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
onkeyup="URLFieldHandler()" onblur="URLFieldHandler()"> onkeyup="URLFieldHandler()" onblur="URLFieldHandler()">
</td> </td>
</tr> </tr>
</tbody>
[% END %] [% END %]
<tr> <tr>
<th><label for="description">Description</label>:</th> <th><label for="description">Description</label>:</th>
...@@ -62,7 +63,7 @@ ...@@ -62,7 +63,7 @@
<input type="text" id="description" name="description" size="60" maxlength="200"> <input type="text" id="description" name="description" size="60" maxlength="200">
</td> </td>
</tr> </tr>
<tr> <tr class="expert_fields">
<th>Content Type:</th> <th>Content Type:</th>
<td> <td>
<em>If the attachment is a patch, check the box below.</em><br> <em>If the attachment is a patch, check the box below.</em><br>
...@@ -89,7 +90,7 @@ ...@@ -89,7 +90,7 @@
onchange="if (this.value) this.form.contenttypemethod[2].checked = true;"> onchange="if (this.value) this.form.contenttypemethod[2].checked = true;">
</td> </td>
</tr> </tr>
<tr> <tr class="expert_fields">
<td> </td> <td> </td>
<td> <td>
[% IF flag_types && flag_types.size > 0 %] [% IF flag_types && flag_types.size > 0 %]
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
'skins/standard/yui/calendar.css' ] 'skins/standard/yui/calendar.css' ]
javascript_urls = [ "js/attachment.js", "js/util.js", javascript_urls = [ "js/attachment.js", "js/util.js",
"js/yui/yahoo-dom-event.js", "js/yui/calendar.js", "js/yui/yahoo-dom-event.js", "js/yui/calendar.js",
"js/field.js" ] "js/field.js", "js/yui/cookie.js", "js/TUI.js" ]
%] %]
<script type="text/javascript"> <script type="text/javascript">
...@@ -159,6 +159,12 @@ function handleWantsAttachment(wants_attachment) { ...@@ -159,6 +159,12 @@ function handleWantsAttachment(wants_attachment) {
} }
} }
TUI_alternates['expert_fields'] = 'Show Advanced Fields';
// Hide the Advanced Fields by default, unless the user has a cookie
// that specifies otherwise.
TUI_hide_default('expert_fields');
--> -->
</script> </script>
...@@ -187,7 +193,16 @@ function handleWantsAttachment(wants_attachment) { ...@@ -187,7 +193,16 @@ function handleWantsAttachment(wants_attachment) {
</tr> </tr>
<tr> <tr>
<td colspan="4">&nbsp;</td> <td colspan="4">
<a id="expert_fields_controller" class="controller bz_default_hidden"
href="javascript:TUI_toggle_class('expert_fields')">Hide
Advanced Fields</a>
[%# Show the link if the browser supports JS %]
<script type="text/javascript">
YAHOO.util.Dom.removeClass('expert_fields_controller',
'bz_default_hidden');
</script>
</td>
</tr> </tr>
<tr> <tr>
...@@ -454,7 +469,7 @@ function handleWantsAttachment(wants_attachment) { ...@@ -454,7 +469,7 @@ function handleWantsAttachment(wants_attachment) {
</tr> </tr>
</tbody> </tbody>
<tbody> <tbody class="expert_fields">
[% USE Bugzilla %] [% USE Bugzilla %]
[% FOREACH field = Bugzilla.active_custom_fields %] [% FOREACH field = Bugzilla.active_custom_fields %]
...@@ -466,6 +481,9 @@ function handleWantsAttachment(wants_attachment) { ...@@ -466,6 +481,9 @@ function handleWantsAttachment(wants_attachment) {
value_span = 3 %] value_span = 3 %]
</tr> </tr>
[% END %] [% END %]
</tbody>
<tbody>
<tr> <tr>
<th>Summary:</th> <th>Summary:</th>
...@@ -501,7 +519,7 @@ function handleWantsAttachment(wants_attachment) { ...@@ -501,7 +519,7 @@ function handleWantsAttachment(wants_attachment) {
</tr> </tr>
[% IF Param("insidergroup") && user.in_group(Param("insidergroup")) %] [% IF Param("insidergroup") && user.in_group(Param("insidergroup")) %]
<tr> <tr class="expert_fields">
<th>&nbsp;</th> <th>&nbsp;</th>
<td colspan="3"> <td colspan="3">
&nbsp;&nbsp; &nbsp;&nbsp;
...@@ -513,9 +531,7 @@ function handleWantsAttachment(wants_attachment) { ...@@ -513,9 +531,7 @@ function handleWantsAttachment(wants_attachment) {
</td> </td>
</tr> </tr>
[% END %] [% END %]
</tbody>
<tbody class="expert_fields">
<tr> <tr>
<th>Attachment:</th> <th>Attachment:</th>
<td colspan="3"> <td colspan="3">
...@@ -550,7 +566,9 @@ function handleWantsAttachment(wants_attachment) { ...@@ -550,7 +566,9 @@ function handleWantsAttachment(wants_attachment) {
</script> </script>
</td> </td>
</tr> </tr>
</tbody>
<tbody class="expert_fields">
[% IF user.in_group('editbugs', product.id) %] [% IF user.in_group('editbugs', product.id) %]
[% IF use_keywords %] [% IF use_keywords %]
<tr> <tr>
...@@ -577,7 +595,7 @@ function handleWantsAttachment(wants_attachment) { ...@@ -577,7 +595,7 @@ function handleWantsAttachment(wants_attachment) {
[% END %] [% END %]
</tbody> </tbody>
<tbody> <tbody class="expert_fields">
[% IF group.size %] [% IF group.size %]
<tr> <tr>
<th>&nbsp;</th> <th>&nbsp;</th>
...@@ -604,7 +622,9 @@ function handleWantsAttachment(wants_attachment) { ...@@ -604,7 +622,9 @@ function handleWantsAttachment(wants_attachment) {
</td> </td>
</tr> </tr>
[% END %] [% END %]
</tbody>
<tbody>
[%# Form controls for entering additional data about the bug being created. %] [%# Form controls for entering additional data about the bug being created. %]
[% Hook.process("form") %] [% Hook.process("form") %]
......
...@@ -188,12 +188,23 @@ ...@@ -188,12 +188,23 @@
type="text/css"> type="text/css">
<![endif]--> <![endif]-->
<script type="text/javascript">
[% IF javascript %] <!--
<script type="text/javascript"> [%# Make some Bugzilla information available to all scripts.
[% javascript %] # We don't import every parameter and constant because we
</script> # don't want to add a lot of uncached JS to every page.
[% END %] #%]
var BUGZILLA = {
param: {
cookiepath: '[% Param('cookiepath') FILTER js %]'
}
};
[% IF javascript %]
[% javascript %]
[% END %]
// -->
</script>
[% IF javascript_urls %] [% IF javascript_urls %]
[% FOREACH javascript_url = javascript_urls %] [% FOREACH javascript_url = javascript_urls %]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment