]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1499503 - Provide some way of dismissing the uplift form
authorKohei Yoshino <kohei.yoshino@gmail.com>
Tue, 6 Nov 2018 15:24:27 +0000 (10:24 -0500)
committerDylan William Hardison <dylan@hardison.net>
Tue, 6 Nov 2018 15:24:27 +0000 (10:24 -0500)
extensions/BMO/template/en/default/hook/flag/type_comment-form.html.tmpl
extensions/FlagTypeComment/web/js/ftc.js
extensions/FlagTypeComment/web/styles/ftc.css

index 7703bed749382a89e70c12688f8e26d8f9bdf6c0..e620dece8bec55585f606548854764a01199f3ec 100644 (file)
@@ -7,8 +7,10 @@
   #%]
 
 <template class="approval-request" data-flags="approval‑mozilla‑beta approval‑mozilla‑release">
-  <fieldset>
-    <legend>Beta/Release Uplift Approval Request</legend>
+  <section>
+    <header>
+      <h3>Beta/Release Uplift Approval Request</h3>
+    </header>
     <table>
       <tr>
         <th id="_ar_beta_i1_label">Feature/[% terms.Bug %] causing the regression</th>
         <td><input type="text" class="long" aria-labelledby="_ar_beta_i10_label"></td>
       </tr>
     </table>
-  </fieldset>
+  </section>
 </template>
 
 <template class="approval-request" data-flags="approval‑mozilla‑esr*">
-  <fieldset>
-    <legend>ESR Uplift Approval Request</legend>
+  <section>
+    <header>
+      <h3>ESR Uplift Approval Request</h3>
+    </header>
     <table>
       <tr>
         <th id="_ar_esr_i1_label">If this is not a sec:{high,crit} [% terms.bug %], please state case for ESR consideration</th>
         <td><input type="text" class="long" aria-labelledby="_ar_esr_i6_label"></td>
       </tr>
     </table>
-    <p>See <a href="https://wiki.mozilla.org/Release_Management/ESR_Landing_Process" target="_blank">ESR Landing Process</a> for more info.</p>
-  </fieldset>
+    <footer>
+      <p>See <a href="https://wiki.mozilla.org/Release_Management/ESR_Landing_Process" target="_blank">ESR Landing Process</a> for more info.</p>
+    </footer>
+  </section>
 </template>
 
 <template class="approval-request" data-flags="approval‑mozilla‑geckoview*">
-  <fieldset>
-    <legend>GeckoView Uplift Approval Request</legend>
+  <section>
+    <header>
+      <h3>GeckoView Uplift Approval Request</h3>
+    </header>
     <table>
       <tr>
         <th id="_ar_gkv_i1_label">If this is not a sec:{high,crit} [% terms.bug %], please state case for consideration</th>
         <td><input type="text" class="long" aria-labelledby="_ar_gkv_i6_label"></td>
       </tr>
     </table>
-    <p>See <a href="https://wiki.mozilla.org/Release_Management/Uplift_rules" target="_blank">Patch uplifting rules</a> for more info.</p>
-  </fieldset>
+    <footer>
+      <p>See <a href="https://wiki.mozilla.org/Release_Management/Uplift_rules" target="_blank">Patch uplifting rules</a> for more info.</p>
+    </footer>
+  </section>
 </template>
 
 <template class="approval-request" data-flags="sec‑approval">
-  <fieldset>
-    <legend>Security Approval Request</legend>
+  <section>
+    <header>
+      <h3>Security Approval Request</h3>
+    </header>
     <table>
       <tr>
         <th id="_ar_sec_i1_label">How easily could an exploit be constructed based on the patch?</th>
         <td><textarea aria-labelledby="_ar_sec_i7_label"></textarea></td>
       </tr>
     </table>
-  </fieldset>
+  </section>
 </template>
index 291b5ff53ed64884550486e7296818901ec62b33..d4d6eab00375853caf8ca14dda0287695add3389 100644 (file)
@@ -34,13 +34,13 @@ Bugzilla.FlagTypeComment = class FlagTypeComment {
   }
 
   /**
-   * Check if a `<fieldset>` is compatible with the given flag. For example, `approval‑mozilla‑beta` matches
-   * `<fieldset data-flags="approval‑mozilla‑beta approval‑mozilla‑release">` while `approval‑mozilla‑esr60`
-   * matches `<fieldset data-flags="approval‑mozilla‑esr*">`.
+   * Check if a fieldset is compatible with the given flag. For example, `approval‑mozilla‑beta` matches
+   * `<section data-flags="approval‑mozilla‑beta approval‑mozilla‑release">` while `approval‑mozilla‑esr60` matches
+   * `<section data-flags="approval‑mozilla‑esr*">`.
    * @param {String} name Flag name, such as `approval‑mozilla‑beta`.
-   * @param {(HTMLFieldSetElement|HTMLTemplateElement)} $element `<fieldset>` or `<template>` element with the
-   * `data-flags` attribute which is a space-separated list of flag names (wildcard chars can be used).
-   * @returns {Boolean} Whether the `<fieldset>` is compatible.
+   * @param {HTMLElement} $element `<section>` or `<template>` element with the `data-flags` attribute which is a
+   * space-separated list of flag names (wildcard chars can be used).
+   * @returns {Boolean} Whether the fieldset is compatible.
    */
   check_compatibility(name, $element) {
     return !!$element.dataset.flags.split(' ')
@@ -48,35 +48,41 @@ Bugzilla.FlagTypeComment = class FlagTypeComment {
   }
 
   /**
-   * Return a list of temporary `<fieldset>`s already inserted to the current page.
-   * @type {Array<HTMLFieldSetElement>}
+   * Return a list of temporary fieldsets already inserted to the current page.
+   * @type {Array.<HTMLElement>}
    */
   get inserted_fieldsets() {
-    return [...this.$fieldset_wrapper.querySelectorAll('fieldset.approval-request')];
+    return [...this.$fieldset_wrapper.querySelectorAll('section.approval-request')];
   }
 
   /**
-   * Find a temporary `<fieldset>` already inserted to the current page by a flag name.
+   * Find a temporary fieldset already inserted to the current page by a flag name.
    * @param {String} name Flag name, such as `approval‑mozilla‑beta`.
-   * @returns {HTMLFieldSetElement} Any `<fieldset>` element.
+   * @returns {HTMLElement} Any `<section>` element.
    */
   find_inserted_fieldset(name) {
     return this.inserted_fieldsets.find($fieldset => this.check_compatibility(name, $fieldset));
   }
 
   /**
-   * Find an available `<fieldset>` embedded in HTML by a flag name.
+   * Find an available fieldset embedded in HTML by a flag name.
    * @param {String} name Flag name, such as `approval‑mozilla‑beta`.
-   * @returns {HTMLFieldSetElement} Any `<fieldset>` element.
+   * @returns {HTMLElement} Any `<section>` element.
    */
   find_available_fieldset(name) {
     for (const $template of this.templates) {
       if (this.check_compatibility(name, $template)) {
-        const $fieldset = $template.content.cloneNode(true).querySelector('fieldset');
+        const $fieldset = $template.content.cloneNode(true).querySelector('section');
 
         $fieldset.className = 'approval-request';
         $fieldset.dataset.flags = $template.dataset.flags;
 
+        // Make the request form dismissable
+        $fieldset.querySelector('header').insertAdjacentHTML('beforeend',
+          '<button type="button" class="dismiss" title="Dismiss" aria-label="Dismiss">' +
+          '<span class="icon" aria-hidden="true"></span></button>');
+        $fieldset.querySelector('button.dismiss').addEventListener('click', () => this.dismiss_onclick($fieldset));
+
         return $fieldset;
       }
     }
@@ -85,8 +91,8 @@ Bugzilla.FlagTypeComment = class FlagTypeComment {
   }
 
   /**
-   * Find a `<select>` element for a requested flag that matches the given `<fieldset>`.
-   * @param {HTMLFieldSetElement} $fieldset `<fieldset>` element with the `data-flags` attribute.
+   * Find a `<select>` element for a requested flag that matches the given fieldset.
+   * @param {HTMLElement} $fieldset `<section>` element with the `data-flags` attribute.
    * @returns {HTMLSelectElement} Any `<select>` element.
    */
   find_select($fieldset) {
@@ -94,6 +100,13 @@ Bugzilla.FlagTypeComment = class FlagTypeComment {
       .find($_select => $_select.value === '?' && this.check_compatibility($_select.dataset.name, $fieldset));
   }
 
+  /**
+   * Hide the original comment box when one or more fieldsets are inserted.
+   */
+  toggle_comment_box() {
+    this.$comment_wrapper.hidden = this.inserted_fieldsets.length > 0;
+  }
+
   /**
    * Add text to the comment box at the end of any existing comment.
    * @param {String} text Comment text to be added.
@@ -112,13 +125,13 @@ Bugzilla.FlagTypeComment = class FlagTypeComment {
     const state = $select.value;
     let $fieldset = this.find_inserted_fieldset(name);
 
-    // Remove the temporary `<fieldset>` if not required. One `<fieldset>` can support multiple flags, so, for example,
+    // Remove the temporary fieldset if not required. One fieldset can support multiple flags, so, for example,
     // if `approval‑mozilla‑release` is unselected but `approval‑mozilla‑beta` is still selected, keep it
     if (state !== '?' && $fieldset && !this.find_select($fieldset)) {
       $fieldset.remove();
     }
 
-    // Insert a temporary `<fieldset>` if available
+    // Insert a temporary fieldset if available
     if (state === '?' && !$fieldset) {
       $fieldset = this.find_available_fieldset(name);
 
@@ -137,18 +150,28 @@ Bugzilla.FlagTypeComment = class FlagTypeComment {
       }
     }
 
-    // Hide the original comment form when one or more `<fieldset>`s are inserted
-    this.$comment_wrapper.hidden = this.inserted_fieldsets.length > 0;
+    this.toggle_comment_box();
+  }
+
+  /**
+   * Called whenever the Dismiss button on a fieldset is clicked. Remove the fieldset once confirmed.
+   * @param {HTMLElement} $fieldset Any `<section>` element.
+   */
+  dismiss_onclick($fieldset) {
+    if (window.confirm(`Do you really want to remove the ${$fieldset.querySelector('h3').innerText} form?`)) {
+      $fieldset.remove();
+      this.toggle_comment_box();
+    }
   }
 
   /**
-   * Convert the input values into comment text and remove the temporary `<fieldset>` before submitting the form.
+   * Convert the input values into comment text and remove the temporary fieldset before submitting the form.
    * @returns {Boolean} Always `true` to allow submitting the form.
    */
   form_onsubmit() {
     for (const $fieldset of this.inserted_fieldsets) {
       const text = [
-        `[${$fieldset.querySelector('legend').innerText}]`,
+        `[${$fieldset.querySelector('h3').innerText}]`,
         ...[...$fieldset.querySelectorAll('tr')].map($tr => {
           const checkboxes = [...$tr.querySelectorAll('input[type="checkbox"]:checked')];
           const $radio = $tr.querySelector('input[type="radio"]:checked');
index a6ab1c18a72c1ee7091be4181e8f05b6feb45022..22ab9d40de1140f26e0d7feb85502ffc0a0f9bba 100644 (file)
   display: none;
 }
 
-fieldset.approval-request {
+section.approval-request {
+  overflow: hidden;
   margin: 0 0 8px;
+  padding: 0 8px 8px;
+  border: 1px solid #999;
+  border-radius: 3px;
 }
 
-fieldset.approval-request:last-child {
+section.approval-request:last-child {
   margin: 0;
 }
 
-fieldset.approval-request legend {
-  font-weight: bold;
+section.approval-request > header {
+  display: flex;
+  align-items: center;
+  margin: 0 -8px 8px;
+  border-bottom: 1px solid #999;
+  background-color: #CCC;
 }
 
-fieldset.approval-request table {
+section.approval-request h3 {
+  flex: auto;
+  margin: 0;
+  padding: 4px 8px;
+  font-size: 14px;
+  font-weight: 600;
+}
+
+section.approval-request button.dismiss {
+  flex: none;
+  border: 0;
+  border-radius: 0;
+  padding: 4px;
+  color: #666;
+  background: none transparent;
+  box-shadow: none;
+  font-weight: normal;
+  text-shadow: none;
+  cursor: default;
+}
+
+section.approval-request button.dismiss .icon {
+  display: block;
+  font-size: 16px;
+  line-height: 100%;
+  font-family: "Material Icons";
+  font-style: normal;
+}
+
+section.approval-request button.dismiss .icon::before {
+  content: "\E5C9";
+}
+
+section.approval-request table {
   width: 100%;
 }
 
-fieldset.approval-request th {
+section.approval-request th {
   padding: .4em;
   width: 20em;
   line-height: 1.25;
@@ -39,23 +80,23 @@ fieldset.approval-request th {
   white-space: normal !important;
 }
 
-fieldset.approval-request td {
+section.approval-request td {
   vertical-align: middle;
 }
 
-fieldset.approval-request label {
+section.approval-request label {
   font-weight: normal !important;
 }
 
-fieldset.approval-request input[type="text"] {
+section.approval-request input[type="text"] {
   width: 10em;
 }
 
-fieldset.approval-request input.long[type="text"] {
+section.approval-request input.long[type="text"] {
   width: 100%;
 }
 
-fieldset.approval-request textarea {
+section.approval-request textarea {
   width: 100%;
   min-height: 5em;
   font-size: inherit;
@@ -64,12 +105,11 @@ fieldset.approval-request textarea {
   resize: vertical;
 }
 
-fieldset.approval-request div {
+section.approval-request div {
   padding: 0 !important;
 }
 
-fieldset.approval-request table ~ p:last-child {
-  margin: .4em;
+section.approval-request > footer {
   text-align: right;
 }