QAX - Disable Jira 'Click to Edit'

禁用 Jira 点击编辑

// ==UserScript==
// @name         QAX - Disable Jira 'Click to Edit'
// @namespace    https://xianghongai.github.io/
// @version      1.0.1
// @description  禁用 Jira 点击编辑
// @author       Nicholas Hsiang
// @icon         https://xinlu.ink/favicon.ico
// @match        http*://jira.*.com/*
// @grant        unsafeWindow
// ==/UserScript==

(function () {
  'use strict';
  console.log('🚀 Disable Jira "Click to Edit"');

  // 字段禁止点击文本编辑,只能通过点击编辑按钮图标操作
  function main() {
    // 可编辑字段
    const $body = document.querySelector('body');

    $body.addEventListener(
      'click',
      (event) => {
        const targetEle = event.target;

        // i. 点击的是“编辑”按钮图标
        const isEdit = hasClass(targetEle, 'aui-iconfont-edit');

        // ii. 点击的是图片、链接
        // img
        // a
        const inWhitelist = ['img', 'a'].includes(targetEle.tagName.toLowerCase());

        if (inWhitelist || isEdit) {
          return true;
        }

        // 1. 父层为可编辑字段 (非 Description)
        const editableFieldParent = getParents(targetEle, '.editable-field:not(#description-val)');
        const isEditableFieldParent = editableFieldParent && hasClass(editableFieldParent, 'inactive');

        // 2. 当前层为可编辑字段 (非 Description)
        const isEditableField = hasClass(targetEle, 'editable-field') && hasClass(targetEle, 'inactive');

        // 3. Description 字段
        const isDescriptionField = getParents(targetEle, '.user-content-block');

        if (isEditableFieldParent || isEditableField || isDescriptionField) {
          event.preventDefault();
          event.stopPropagation();

          return false;
        }
      },
      true
    );
  }

  function keyboardShortcut() {
    document.addEventListener('keydown', function (event) {
      // 按 ALT+L 添加 Link
      if (event.altKey && event.key.toLowerCase() === 'l') {
        document.querySelector('#link-issue')?.click()
      }
    });
  }

  main();

  keyboardShortcut();

  // #region COMMON
  function hasClass(el, className) {
    if (el.classList) {
      return el.classList.contains(className);
    }
    return !!el.className.match(
      new RegExp('(\\s|^)' + className + '(\\s|$)')
    );
  }

  function getParents(elem, selector) {
    for (; elem && elem !== document; elem = elem.parentNode) {
      if (elem.matches(selector)) return elem;
    }
    return null;
  }
  // #endregion
})();