Chaoxing Paste Unlock

Remove paste restrictions in Chaoxing AI evaluate code editor pages.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Chaoxing Paste Unlock
// @name:zh-CN   超星粘贴限制解除
// @namespace    https://mooc2-ans.chaoxing.com/
// @version      0.1.1
// @description  Remove paste restrictions in Chaoxing AI evaluate code editor pages.
// @description:zh-CN 解除超星 AI 作答代码编辑器页面的粘贴限制。
// @author       GrassskyR
// @homepageURL  https://github.com/GrassskyR/Fuck-chaoxing-AntiPaste
// @supportURL   https://github.com/GrassskyR/Fuck-chaoxing-AntiPaste/issues
// @license      MIT
// @match        https://mooc2-ans.chaoxing.com/mooc2-ans/ai-evaluate/v2/answer*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function () {
  'use strict';

  const POLL_INTERVAL_MS = 500;
  const LOG_PREFIX = '[chaoxing-paste-unlock]';
  const win = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;

  function log(message) {
    console.debug(`${LOG_PREFIX} ${message}`);
  }

  function unlockApp(app) {
    if (!app) {
      return false;
    }

    let changed = false;

    if (app.publishSetting && app.publishSetting.notAllowPaste !== 0) {
      app.publishSetting.notAllowPaste = 0;
      changed = true;
    }

    if (app.current && app.current.publishSetting && app.current.publishSetting.notAllowPaste !== 0) {
      app.current.publishSetting.notAllowPaste = 0;
      changed = true;
    }

    if (typeof app.handlePasteContent === 'function' && !app.handlePasteContent.__pasteUnlocked) {
      const unlockedHandler = function handlePasteContentUnlocked() {
        return true;
      };

      unlockedHandler.__pasteUnlocked = true;
      unlockedHandler.__original = app.handlePasteContent;
      app.handlePasteContent = unlockedHandler;
      changed = true;
    }

    return changed;
  }

  function unlockEditors() {
    let changed = false;
    const editorNodes = document.querySelectorAll('.CodeMirror');

    editorNodes.forEach((node) => {
      const editor = node && node.CodeMirror;
      if (!editor) {
        return;
      }

      if (editor.getOption('readOnly') === true) {
        return;
      }

      const inputField = typeof editor.getInputField === 'function' ? editor.getInputField() : node.querySelector('textarea');
      if (!inputField || inputField.__pasteUnlockCaptureInstalled) {
        return;
      }

      inputField.addEventListener(
        'paste',
        (event) => {
          event.stopImmediatePropagation();
        },
        true
      );

      inputField.__pasteUnlockCaptureInstalled = true;
      changed = true;
    });

    return changed;
  }

  function patchRuntime() {
    const appChanged = unlockApp(win.app);
    const editorChanged = unlockEditors();

    if (appChanged || editorChanged) {
      log('paste restriction removed');
    }
  }

  patchRuntime();
  window.addEventListener('load', patchRuntime, { once: false });
  setInterval(patchRuntime, POLL_INTERVAL_MS);
})();