You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

projectdoc Toolbox

Enforces comments in a specific format when documents are edited.

Identifier
de.smartics.userscripts.confluence.force-comment
Type
Repository
Since
1.0

The script checks in the Confluence page editor whether or not the comment adheres to the required format. If not the page cannot be saved.

If the change is either a feature or a fix, then the watchers of the page will be notified.

Code

force-comment.js
/*
 * Copyright 2019-2020 Kronseder & Reiner GmbH, smartics
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

"use strict";

AJS.toInit(function () {
  const logToConsole = false;
  const commentPrefixes = ["fix: ", "feat: ", "refactor: ", "chore: ", "style: "];
  const notificationRequiredIndex = 1;

  if (logToConsole) {
    AJS.log("[force-comments] Force comment with: " + commentPrefixes);
  }

  const isValidComment = function (comment) {
    if (comment) {
      for (let i = 0; i < commentPrefixes.length; i++) {
        const commentPrefix = commentPrefixes[i];
        if (comment.startsWith(commentPrefix) &&
          comment.length > commentPrefix.length) {
          return true;
        }
      }
    }
    return false;
  };

  const requiresNotification = function (comment) {
    if (comment) {
      for (let i = 0; i <= notificationRequiredIndex; i++) {
        const commentPrefix = commentPrefixes[i];
        if (comment.startsWith(commentPrefix)) {
          return true;
        }
      }
    }
    return false;
  };

  const createHelpDialog = function ($element) {
    if (AJS.$("#userscripts-commitMessages-helpDialog-show-button").length) {
      return;
    }
    const button = AJS.$("<button id=\"userscripts-commitMessages-helpDialog-show-button\" class=\"aui-button toolbar-item\" style=\"margin-right: 10px;\"><span class=\"aui-icon aui-icon-small aui-iconfont-question-filled\">Help on Commit Message Format</span></button>\n");
    $element.before(button);

    AJS.$("#userscripts-commitMessages-helpDialog-show-button").on('click', function (e) {
      e.preventDefault();

      const dialog = AJS.$("<section\n" +
        "    id=\"userscripts-commitMessages-helpDialog\"\n" +
        "    class=\"aui-dialog2 aui-dialog2-medium aui-layer\"\n" +
        "    role=\"dialog\"\n" +
        "    tabindex=\"-1\"\n" +
        "    data-aui-modal=\"false\"" +
        "    data-aui-remove-on-hide=\"true\"" +
        "    aria-labelledby=\"userscripts-commitMessages-helpDialog-show-button--heading\"\n" +
        "    hidden\n" +
        ">\n" +
        "    <header class=\"aui-dialog2-header\">\n" +
        "        <h1 class=\"aui-dialog2-header-main\" id=\"userscripts-commitMessages-helpDialog-show-button--heading\">Help: Commit message format</h1>\n" +
        "    </header>\n" +
        "    <div class=\"aui-dialog2-content\">\n" +
        "        <p>Use the following format for your commit messages.</p>\n" +
        "<table class=\"aui\">\n" +
        "    <thead>\n" +
        "        <tr>\n" +
        "            <th id=\"type\">Type</th>\n" +
        "            <th id=\"description\">Description</th>\n" +
        "            <th id=\"notify\" style=\"text-align:center;\">Notify</th>\n" +
        "            <th id=\"example\">Example</th>\n" +
        "        </tr>\n" +
        "    </thead>\n" +
        "    <tbody>\n" +
        "        <tr>\n" +
        "            <td headers=\"type\" style=\"font-weight: bold;\">Feature</td>\n" +
        "            <td headers=\"description\">Adds essential new information.</td>\n" +
        "            <td headers=\"notify\" style=\"text-align:center;\">\n<span class=\"aui-icon aui-icon-small aui-iconfont-approve\">Checks the 'Notify watchers' checkbox</span></td>\n" +
        "            <td headers=\"example\">\n" +
        "                <code>feat: Add section on error handling.</code>\n" +
        "            </td>\n" +
        "        </tr>\n" +
        "        <tr>\n" +
        "            <td headers=\"type\" style=\"font-weight: bold;\">Fix</td>\n" +
        "            <td headers=\"description\">Fixes an issue or false information.</td>\n" +
        "            <td headers=\"notify\" style=\"text-align:center;\">\n<span class=\"aui-icon aui-icon-small aui-iconfont-approve\">Checks the 'Notify watchers' checkbox</span></td>\n" +
        "            <td headers=\"example\">\n" +
        "                <code>fix: Clarify section on user administration which is misleading.</code>\n" +
        "            </td>\n" +
        "        </tr>\n" +
        "        <tr>\n" +
        "            <td headers=\"type\" style=\"font-weight: bold;\">Chore</td>\n" +
        "            <td headers=\"description\">Necessary adjustments without regards to content.</td>\n" +
        "            <td headers=\"notify\" style=\"text-align:center;\">\n<span class=\"aui-icon aui-icon-small aui-iconfont-cross-circle\">Unchecks the 'Notify watchers' checkbox</span></td>\n" +
        "            <td headers=\"example\">\n" +
        "                <code>chore: Update icon to higher resolution.</code>\n" +
        "            </td>\n" +
        "        </tr>\n" +
        "        <tr>\n" +
        "            <td headers=\"type\" style=\"font-weight: bold;\">Refactor</td>\n" +
        "            <td headers=\"description\">Reorganize sections or rename elements.</td>\n" +
        "            <td headers=\"notify\" style=\"text-align:center;\">\n<span class=\"aui-icon aui-icon-small aui-iconfont-cross-circle\">Unchecks the 'Notify watchers' checkbox</span></td>\n" +
        "            <td headers=\"example\">\n" +
        "                <code>refactor: Split administration section into three subsections.</code>\n" +
        "            </td>\n" +
        "        </tr>\n" +
        "        <tr>\n" +
        "            <td headers=\"type\" style=\"font-weight: bold;\">Style</td>\n" +
        "            <td headers=\"description\">Change the wording, remove typos, or fix grammar.</td>\n" +
        "            <td headers=\"notify\" style=\"text-align:center;\">\n<span class=\"aui-icon aui-icon-small aui-iconfont-cross-circle\">Unchecks the 'Notify watchers' checkbox</span></td>\n" +
        "            <td headers=\"example\">\n" +
        "                <code>style: Replace with active voice to address the reader.</code>\n" +
        "            </td>\n" +
        "        </tr>\n" +
        "    </tbody>\n" +
        "</table>" +
        "    </div>\n" +
        "    <footer class=\"aui-dialog2-footer\">\n" +
        "        <div class=\"aui-dialog2-footer-actions\">\n" +
        "            <button id=\"userscripts-commitMessages-helpDialog-submit-button\" class=\"aui-button aui-button-primary\">Okay</button>\n" +
        "        </div>\n" +
        "    </footer>\n" +
        "</section>");

      $element.before(dialog);

      AJS.$("#userscripts-commitMessages-helpDialog-submit-button").on('click', function (e) {
        e.preventDefault();
        AJS.dialog2("#userscripts-commitMessages-helpDialog").hide();
      });

      AJS.dialog2("#userscripts-commitMessages-helpDialog").show();
    });
  };

  AJS.$(function () {
    if (logToConsole) {
      AJS.log("[force-comments] Analysing page elements: " + commentPrefixes);
    }
    const $versionComment = AJS.$('#versionComment');
    const $publishButton = AJS.$('#rte-button-publish');
    const $notify = AJS.$('#notifyWatchers');
    const originalNotify = $notify.prop('checked');

    createHelpDialog($versionComment);

    if ($versionComment && $publishButton) {
      $versionComment.bind("input change", function () {
        const comment = $versionComment.val();
        if (isValidComment(comment)) {
          $publishButton.prop('disabled', false);
          if (requiresNotification(comment)) {
            $notify.prop('checked', true);
          } else {
            $notify.prop('checked', originalNotify);
          }
        } else {
          $publishButton.prop('disabled', true);
        }
      });

      const comment = $versionComment.val();
      if (!isValidComment(comment)) {
        $publishButton.prop('disabled', true);
      }
    }
  });
});

Details

Typically there is no need to enforce specific comments for each and every change for a page on a Confluence server. Typically versioned documents are located in a specific space. To activate the script for spaces with versioned documents, the userscripts administrator may define a space category, like versioned, to be set.
  • No labels