summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDylan William Hardison <dylan@hardison.net>2015-01-05 19:27:48 +0100
committerDylan William Hardison <dylan@hardison.net>2015-01-05 19:27:48 +0100
commit7834fbf656adfa48344a6246611c3498831dc850 (patch)
tree397b8494bb32e093c6dd6278b0ec2829f6b35cbd
parentc840c16f2870c054edb996875d46942d230e1567 (diff)
downloadbugzilla-7834fbf656adfa48344a6246611c3498831dc850.tar.gz
bugzilla-7834fbf656adfa48344a6246611c3498831dc850.tar.xz
Bug 1050232 - Improve layout of guided bug entry product selection
-rw-r--r--extensions/GuidedBugEntry/template/en/default/bug/create/comment-guided.txt.tmpl3
-rw-r--r--extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl121
-rw-r--r--extensions/GuidedBugEntry/template/en/default/guided/products.html.tmpl36
-rw-r--r--extensions/GuidedBugEntry/web/js/guided.js81
-rw-r--r--extensions/GuidedBugEntry/web/js/products.js15
-rw-r--r--extensions/GuidedBugEntry/web/style/guided.css59
-rw-r--r--t/008filter.t2
7 files changed, 205 insertions, 112 deletions
diff --git a/extensions/GuidedBugEntry/template/en/default/bug/create/comment-guided.txt.tmpl b/extensions/GuidedBugEntry/template/en/default/bug/create/comment-guided.txt.tmpl
index 6b0de9466..31408b538 100644
--- a/extensions/GuidedBugEntry/template/en/default/bug/create/comment-guided.txt.tmpl
+++ b/extensions/GuidedBugEntry/template/en/default/bug/create/comment-guided.txt.tmpl
@@ -3,6 +3,9 @@
User Agent: [% cgi.param('user_agent') %]
[% IF cgi.param('build_id') %]
Build ID: [% cgi.param('build_id') %][% END %]
+[% IF cgi.param('firefox_for_android') %]
+Firefox for Android
+[% END %]
[% IF cgi.param('bug_steps') %]
Steps to reproduce:
diff --git a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
index 5b57a0900..9a1c09e6f 100644
--- a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
+++ b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
@@ -14,15 +14,12 @@
'extensions/ProdCompSearch/web/js/prod_comp_search.js',
'js/field.js', 'js/TUI.js', 'js/bug.js' ] %]
-[% yui_modules = [ 'history', 'datatable', 'container' ] %]
-[% yui_modules.push('autocomplete') %]
-
[% PROCESS global/header.html.tmpl
title = "Enter A Bug"
javascript_urls = js_urls
style_urls = [ 'extensions/GuidedBugEntry/web/style/guided.css',
'js/yui/assets/skins/sam/container.css' ]
- yui = yui_modules
+ yui = [ 'history', 'datatable', 'container', 'autocomplete' ]
%]
<iframe id="yui-history-iframe" src="extensions/GuidedBugEntry/web/yui-history-iframe.txt"></iframe>
@@ -103,19 +100,15 @@ dupes.setLabels(
show = "all"
%]
-<table id="products">
+<ul class="product-list">
[% INCLUDE 'guided/products.html.tmpl' %]
-[% INCLUDE product_block
+[% WRAPPER product_block
name="Other Products"
icon="other.png"
- desc="Other Mozilla products which aren't listed here"
- onclick="guided.setStep('otherProducts')"
-%]
-</table>
-
-<h3>
- Or search for a Product:
-</h3>
+ onclick="guided.setStep('otherProducts')" %]
+Other Mozilla products which aren't listed here
+[% END %]
+</ul>
<div id="prod_comp_search_main">
[% PROCESS prodcompsearch/form.html.tmpl
@@ -123,7 +116,6 @@ dupes.setLabels(
format = "guided"
script_name = "enter_bug.cgi" %]
</div>
-
</div>
[% END %]
@@ -141,32 +133,24 @@ dupes.setLabels(
[% END %]
[% END %]
[% END %]
- <tr>
- <td class="product_img">
- <a href="javascript:void(0)"
+ <li
[% IF onclick %]
onclick="[% onclick FILTER html %]"
[% ELSE %]
onclick="product.select('[% name FILTER js %]')"
- [% END %]
- ><img src="extensions/BMO/web/producticons/[% icon FILTER uri %]" width="64" height="64"
- ></a>
- </td>
- <td>
- <h2>
- <a href="javascript:void(0)"
- [% IF onclick %]
- onclick="[% onclick FILTER html %]"
+ [% END %]>
+ <span class="product-item">
+ <img src="extensions/BMO/web/producticons/[% icon FILTER uri %]" class="product-icon" >
+ <a href="javascript:void(0)">[% caption FILTER html %]</a>
+ <p>
+ [% IF content %]
+ [% content FILTER none %]
[% ELSE %]
- onclick="product.select('[% name FILTER js %]')"
+ [% desc FILTER html_light %]
[% END %]
- >[% caption FILTER html %]</a>
- </h2>
- <p>
- [% desc FILTER html_light %]
</p>
- </td>
- </tr>
+ </span>
+ </li>
[% END %]
[%############################################################################%]
@@ -300,11 +284,25 @@ Product: <b><span id="dupes_product_name">?</span></b>:
</p>
<table border="0" cellpadding="5" cellspacing="0" id="product_support" class="hidden">
-<tr>
-<td>
- <img src="extensions/GuidedBugEntry/web/images/message.png" width="24" height="24">
-</td>
-<td id="product_support_message">&nbsp;</td>
+ <tr>
+ <td>
+ <img src="extensions/GuidedBugEntry/web/images/message.png" width="24" height="24">
+ </td>
+ <td id="product_support_message">&nbsp;</td>
+ </tr>
+</table>
+
+<table border="0" cellpadding="5" cellspacing="0" id="l10n_message">
+ <tr>
+ <td>
+ <img src="extensions/BMO/web/producticons/localization.png" width="24" height="24">
+ </td>
+ <td>
+ <a href="javascript:void(0)" id="l10n_link">
+ <span id="l10n_product"></span> is poorly translated into my native language.
+ </a>
+ </td>
+ </tr>
</table>
<div id="dupe_form">
@@ -358,7 +356,7 @@ explain how to write effective [% terms.bug %] reports.</li>
<table id="bugForm" cellspacing="0">
-<tr class="odd">
+<tr>
<td class="label">Summary:</td>
<td width="100%" colspan="2">
<input name="short_desc" id="short_desc" class="textInput" spellcheck="true">
@@ -374,7 +372,7 @@ explain how to write effective [% terms.bug %] reports.</li>
</td>
</tr>
-<tr class="even">
+<tr>
<td class="label">Product:</td>
<td id="productTD">
<span id="product_label"></span>
@@ -392,7 +390,7 @@ explain how to write effective [% terms.bug %] reports.</li>
</div>
</tr>
-<tr class="odd" id="componentTR">
+<tr id="componentTR">
<td valign="top">
<div class="label">
Component:
@@ -415,7 +413,7 @@ explain how to write effective [% terms.bug %] reports.</li>
</div>
</tr>
-<tr class="even">
+<tr>
<td class="label" colspan="3">What did you do? (steps to reproduce)</td>
<td valign="top">
[% PROCESS help id="steps_help" %]
@@ -433,12 +431,12 @@ explain how to write effective [% terms.bug %] reports.</li>
</div>
</td>
</tr>
-<tr class="even">
+<tr>
<td colspan="3"><textarea id="bug_steps" name="bug_steps" rows="5"></textarea></td>
<td>&nbsp;</td>
</tr>
-<tr class="odd">
+<tr>
<td class="label" colspan="3">What happened? (actual results)</td>
<td valign="top">
[% PROCESS help id="actual_help" %]
@@ -446,12 +444,12 @@ explain how to write effective [% terms.bug %] reports.</li>
What happened after you performed the steps above?
</div>
</tr>
-<tr class="odd">
+<tr>
<td colspan="3"><textarea id="actual" name="actual" rows="5"></textarea></td>
<td>&nbsp;</td>
</tr>
-<tr class="even">
+<tr>
<td class="label" colspan="3">What should have happened? (expected results)</td>
<td valign="top">
[% PROCESS help id="expected_help" %]
@@ -459,12 +457,12 @@ explain how to write effective [% terms.bug %] reports.</li>
What should the software have done instead?
</div>
</tr>
-<tr class="even">
+<tr>
<td colspan="3"><textarea id="expected" name="expected" rows="5"></textarea></td>
<td>&nbsp;</td>
</tr>
-<tr class="odd">
+<tr>
<td class="label">Attach a file:</td>
<td colspan="2">
<input type="file" name="data" id="data" size="50" onchange="bugForm.onFileChange()">
@@ -479,13 +477,13 @@ explain how to write effective [% terms.bug %] reports.</li>
</div>
</td>
</tr>
-<tr class="odd">
+<tr>
<td class="label">File Description:</td>
<td colspan="2"><input type="text" name="description" id="data_description" class="textInput" disabled></td>
<td>&nbsp;</td>
</tr>
-<tr class="even">
+<tr>
<td class="label">Security:</td>
<td colspan="2">
<table border="0" cellpadding="0" cellspacing="0">
@@ -503,7 +501,26 @@ explain how to write effective [% terms.bug %] reports.</li>
<td>&nbsp;</td>
</tr>
-<tr class="odd">
+<tr id="details">
+ <td class="label">Additional Details:</td>
+ <td colspan="2">
+ <table border="0" cellpadding="0" cellspacing="0">
+ <tr id="firefox_for_android_row">
+ <td>
+ <input type="checkbox" id="firefox_for_android" name="firefox_for_android" value="1">
+ </td>
+ <td>
+ <label for="firefox_for_android">This is a problem with Firefox on my phone or tablet.</label>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+
+<tr id="submitTR">
<td>&nbsp;</td>
<td colspan="2" id="submitTD">
<input type="submit" id="submit" value="Submit [% terms.Bug %]">
diff --git a/extensions/GuidedBugEntry/template/en/default/guided/products.html.tmpl b/extensions/GuidedBugEntry/template/en/default/guided/products.html.tmpl
index f4e7b81ff..67ad392a1 100644
--- a/extensions/GuidedBugEntry/template/en/default/guided/products.html.tmpl
+++ b/extensions/GuidedBugEntry/template/en/default/guided/products.html.tmpl
@@ -6,23 +6,19 @@
# defined by the Mozilla Public License, v. 2.0.
#%]
-[% INCLUDE product_block
+[% WRAPPER product_block
name="Firefox"
icon="firefox.png"
%]
+For [% terms.bugs %] in Firefox, the Mozilla Foundation's web browser.
+
+(<a href="https://www.mozilla.org/en-US/firefox/desktop/">more info</a>)
+[% END %]
[% INCLUDE product_block
name="Firefox OS"
icon="firefox_os.png"
%]
[% INCLUDE product_block
- name="Firefox for Android"
- icon="firefox_android.png"
-%]
-[% INCLUDE product_block
- name="Marketplace"
- icon="marketplace.png"
-%]
-[% INCLUDE product_block
name="Webmaker"
icon="webmaker.png"
%]
@@ -30,21 +26,9 @@
name="Thunderbird"
icon="thunderbird.png"
%]
-[% INCLUDE product_block
- name="SeaMonkey"
- icon="seamonkey.png"
-%]
-[% INCLUDE product_block
- name="Core"
- icon="component.png"
-%]
-[% INCLUDE product_block
- name="Mozilla Localizations"
- icon="localization.png"
- caption="Localizations"
-%]
-[% INCLUDE product_block
- name="Mozilla Services"
- icon="sync.png"
- caption="Services"
+[% WRAPPER product_block
+ name="Marketplace"
+ icon="marketplace.png"
%]
+Mozilla's website to bring personalized discovery, worldwide distribution, and easy payments to the largest platform for app development: the Web. (<a href="https://wiki.mozilla.org/Marketplace">more info</a>)
+[% END %]
diff --git a/extensions/GuidedBugEntry/web/js/guided.js b/extensions/GuidedBugEntry/web/js/guided.js
index a3888783b..6a4419ddf 100644
--- a/extensions/GuidedBugEntry/web/js/guided.js
+++ b/extensions/GuidedBugEntry/web/js/guided.js
@@ -87,7 +87,7 @@ var guided = {
},
setAdvancedLink: function() {
- href = 'enter_bug.cgi?format=__default__' +
+ var href = 'enter_bug.cgi?format=__default__' +
'&product=' + encodeURIComponent(product.getName()) +
'&short_desc=' + encodeURIComponent(dupes.getSummary());
Dom.get('advanced_img').href = href;
@@ -187,12 +187,10 @@ var product = {
if (products[productName] && products[productName].noComponentSelection) {
if (!Dom.hasClass('componentTR', 'hidden')) {
Dom.addClass('componentTR', 'hidden');
- bugForm.toggleOddEven();
}
} else {
if (Dom.hasClass('componentTR', 'hidden')) {
Dom.removeClass('componentTR', 'hidden');
- bugForm.toggleOddEven();
}
}
@@ -209,7 +207,7 @@ var product = {
{
success: function(res) {
try {
- data = YAHOO.lang.JSON.parse(res.responseText);
+ var data = YAHOO.lang.JSON.parse(res.responseText);
if (data.error)
throw(data.error.message);
if (data.result.products.length == 0)
@@ -416,7 +414,7 @@ var dupes = {
'jsonrpc.cgi',
{
success: function(res) {
- data = YAHOO.lang.JSON.parse(res.responseText);
+ var data = YAHOO.lang.JSON.parse(res.responseText);
if (data.error)
throw(data.error.message);
dupes._buildCcHTML(el, bugID, bugStatus, follow);
@@ -446,6 +444,7 @@ var dupes = {
this._elList.innerHTML = '';
this._showProductSupport();
this._currentSearchQuery = '';
+ this._elSummary.focus();
},
_showProductSupport: function() {
@@ -469,6 +468,17 @@ var dupes = {
// a search has happened
Dom.addClass('advanced', 'hidden');
Dom.addClass('dupes_continue_button_top', 'hidden');
+ var prod = product.getName();
+ if (products[prod] && products[prod].l10n) {
+ Dom.removeClass('l10n_message', 'hidden');
+ Dom.get('l10n_product').textContent = product.getName();
+ Dom.get('l10n_link').onclick = function () {
+ product.select('Mozilla Localizations');
+ };
+ }
+ else {
+ Dom.addClass('l10n_message', 'hidden');
+ }
if (!this._elSearch.disabled && this.getSummary().length >= 4) {
// do an immediate search after a page refresh if there's a query
@@ -580,6 +590,9 @@ var dupes = {
var bugForm = {
_visibleHelpPanel: null,
_mandatoryFields: [],
+ _conditionalDetails: [
+ { check: function () { return product.getName() == 'Firefox'; }, id: 'firefox_for_android_row' }
+ ],
onInit: function() {
var user_agent = navigator.userAgent;
@@ -596,6 +609,7 @@ var bugForm = {
onShow: function() {
// check for a forced format
var productName = product.getName();
+ var visibleCount = 0;
if (products[productName] && products[productName].format) {
Dom.addClass('advanced', 'hidden');
document.location.href = 'enter_bug.cgi?format=' + encodeURIComponent(products[productName].format) +
@@ -614,6 +628,24 @@ var bugForm = {
for (var i = 0, n = this._mandatoryFields.length; i < n; i++) {
Dom.removeClass(this._mandatoryFields[i], 'missing');
}
+
+ this._conditionalDetails.forEach(function (cond) {
+ if (cond.check()) {
+ visibleCount++;
+ Dom.removeClass(cond.id, 'hidden');
+ }
+ else {
+ Dom.addClass(cond.id, 'hidden');
+ }
+ });
+ if (visibleCount > 0) {
+ Dom.removeClass('details', 'hidden');
+ Dom.removeClass('submitTR', 'even');
+ }
+ else {
+ Dom.addClass('details', 'hidden');
+ Dom.addClass('submitTR', 'even');
+ }
},
resetSubmitButton: function() {
@@ -662,16 +694,18 @@ var bugForm = {
// check for the default component
var defaultRegex;
if (product.getPreselectedComponent()) {
- defaultRegex = new RegExp('^' + quoteMeta(product.getPreselectedComponent()) + '$', 'i')
+ defaultRegex = new RegExp('^' + quoteMeta(product.getPreselectedComponent()) + '$', 'i');
} else if(products[productName] && products[productName].defaultComponent) {
- defaultRegex = new RegExp('^' + quoteMeta(products[productName].defaultComponent) + '$', 'i')
+ defaultRegex = new RegExp('^' + quoteMeta(products[productName].defaultComponent) + '$', 'i');
} else {
defaultRegex = new RegExp('General', 'i');
}
var preselectedComponent = false;
- for (var i = 0, n = product.details.components.length; i < n; i++) {
- var component = product.details.components[i];
+ var i, n;
+ var component;
+ for (i = 0, n = product.details.components.length; i < n; i++) {
+ component = product.details.components[i];
if (component.is_active == '1') {
if (defaultRegex.test(component.name)) {
preselectedComponent = component.name;
@@ -686,8 +720,8 @@ var bugForm = {
}
// build component select
- for (var i = 0, n = product.details.components.length; i < n; i++) {
- var component = product.details.components[i];
+ for (i = 0, n = product.details.components.length; i < n; i++) {
+ component = product.details.components[i];
if (component.is_active == '1') {
elComponents.options[elComponents.options.length] =
new Option(component.name, component.name);
@@ -695,7 +729,7 @@ var bugForm = {
}
var validComponent = false;
- for (var i = 0, n = elComponents.options.length; i < n && !validComponent; i++) {
+ for (i = 0, n = elComponents.options.length; i < n && !validComponent; i++) {
if (elComponents.options[i].value == elComponent.value)
validComponent = true;
}
@@ -713,7 +747,7 @@ var bugForm = {
// build versions
var defaultVersion = '';
var currentVersion = Dom.get('version').value;
- for (var i = 0, n = product.details.versions.length; i < n; i++) {
+ for (i = 0, n = product.details.versions.length; i < n; i++) {
var version = product.details.versions[i];
if (version.is_active == '1') {
elVersions.options[elVersions.options.length] =
@@ -728,7 +762,7 @@ var bugForm = {
if (products[productName] && products[productName].version) {
var detectedVersion = products[productName].version();
var options = elVersions.options;
- for (var i = 0, n = options.length; i < n; i++) {
+ for (i = 0, n = options.length; i < n; i++) {
if (options[i].value == detectedVersion) {
defaultVersion = detectedVersion;
break;
@@ -815,18 +849,6 @@ var bugForm = {
return false;
},
- toggleOddEven: function() {
- var rows = Dom.get('bugForm').getElementsByTagName('TR');
- var doToggle = false;
- for (var i = 0, n = rows.length; i < n; i++) {
- if (doToggle) {
- rows[i].className = rows[i].className == 'odd' ? 'even' : 'odd';
- } else {
- doToggle = rows[i].id == 'componentTR';
- }
- }
- },
-
_getFilename: function() {
var filename = Dom.get('data').value;
if (!filename)
@@ -838,8 +860,9 @@ var bugForm = {
_mandatoryMissing: function() {
var result = new Array();
for (var i = 0, n = this._mandatoryFields.length; i < n; i++ ) {
- id = this._mandatoryFields[i];
- el = Dom.get(id);
+ var id = this._mandatoryFields[i];
+ var el = Dom.get(id);
+ var value;
if (el.type.toString() == "checkbox") {
value = el.checked;
@@ -920,7 +943,7 @@ var bugForm = {
el.panel.hide();
this._visibleHelpPanel = null;
}
-}
+};
function quoteMeta(value) {
return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
diff --git a/extensions/GuidedBugEntry/web/js/products.js b/extensions/GuidedBugEntry/web/js/products.js
index dfc830d0f..43b2a8e5b 100644
--- a/extensions/GuidedBugEntry/web/js/products.js
+++ b/extensions/GuidedBugEntry/web/js/products.js
@@ -19,6 +19,9 @@
*/
var products = {
+ "addons.mozilla.org": {
+ l10n: true
+ },
"Firefox": {
related: [ "Core", "Toolkit" ],
@@ -40,6 +43,7 @@ var products = {
defaultComponent: "Untriaged",
noComponentSelection: true,
detectPlatform: true,
+ l10n: true,
support:
'If you are new to Firefox or Bugzilla, please consider checking ' +
'<a href="http://support.mozilla.com/">' +
@@ -50,6 +54,7 @@ var products = {
"Firefox for Android": {
related: [ "Core", "Toolkit" ],
detectPlatform: true,
+ l10n: true,
support:
'If you are new to Firefox or Bugzilla, please consider checking ' +
'<a href="http://support.mozilla.com/">' +
@@ -60,6 +65,7 @@ var products = {
"SeaMonkey": {
related: [ "Core", "Toolkit", "MailNews Core" ],
detectPlatform: true,
+ l10n: true,
version: function() {
var re = /SeaMonkey\/(\d+)\.(\d+)/i;
var match = re.exec(navigator.userAgent);
@@ -73,6 +79,10 @@ var products = {
}
},
+ "Calendar": {
+ l10n: true
+ },
+
"Camino": {
related: [ "Core", "Toolkit" ],
detectPlatform: true
@@ -85,6 +95,7 @@ var products = {
"Thunderbird": {
related: [ "Core", "Toolkit", "MailNews Core" ],
detectPlatform: true,
+ l10n: true,
defaultComponent: "Untriaged",
componentFilter : function(components) {
var index = -1;
@@ -101,6 +112,10 @@ var products = {
}
},
+ "Marketplace": {
+ l10n: true
+ },
+
"Penelope": {
related: [ "Core", "Toolkit", "MailNews Core" ]
},
diff --git a/extensions/GuidedBugEntry/web/style/guided.css b/extensions/GuidedBugEntry/web/style/guided.css
index f06715eab..eca500c69 100644
--- a/extensions/GuidedBugEntry/web/style/guided.css
+++ b/extensions/GuidedBugEntry/web/style/guided.css
@@ -31,9 +31,54 @@
visibility: hidden;
}
-.step {
- margin-left: 20px;
- margin-bottom: 25px;
+#steps {
+ max-width: 1200px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.product-icon {
+ float: left;
+ margin: 8px 15px 8px 0px;
+ height: 64px;
+ width: 64px;
+}
+
+#product_step {
+ max-width: 1200px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+ul.product-list {
+ list-style: outside none none;
+ margin: 0px -10px 20px;
+ padding: 0px;
+}
+
+ul.product-list > li {
+ cursor: pointer;
+ height: 168px;
+ min-height: 166px;
+
+ background-color: #FFF;
+ background-image: linear-gradient(0deg, #F6F4EC, #FFF);
+ border-radius: 6px;
+ background-clip: padding-box;
+ box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
+ display: inline-block;
+ margin: 5px 5px 5px;
+ padding: 1px;
+ position: relative;
+ vertical-align: top;
+ width: 300px;
+ word-wrap: break-word;
+ z-index: 1;
+}
+
+ul.product-list > li > .product-item {
+ display: block;
+ padding: 10px;
}
#steps a img {
@@ -42,6 +87,8 @@
#advanced {
margin-top: 50px;
+ text-align: right;
+ margin-left: auto;
}
#advanced img {
@@ -160,10 +207,14 @@
padding: 5px;
}
-#bugForm .even th, #bugForm .even td {
+#bugForm tr:nth-child(even) td, #bugForm tr:nth-child(even) th {
background: #e0e0e0;
}
+#bugForm tr.odd td {
+ background: inherit;
+}
+
#bugForm .label {
text-align: left;
font-weight: bold;
diff --git a/t/008filter.t b/t/008filter.t
index d0c0311f6..0d91fb7c2 100644
--- a/t/008filter.t
+++ b/t/008filter.t
@@ -176,7 +176,7 @@ sub directive_ok {
BLOCK|USE|ELSE|NEXT|LAST|DEFAULT|FLUSH|
ELSIF|SET|SWITCH|CASE|WHILE|RETURN|STOP|
TRY|CATCH|FINAL|THROW|CLEAR|MACRO|FILTER|
- CALL)/x;
+ CALL|WRAPPER)/x;
# ? :
if ($directive =~ /.+\?(.+):(.+)/) {