コンテンツにスキップ

利用者:Yuukin0248/saveEditingText.js

お知らせ: 保存した後、ブラウザのキャッシュをクリアしてページを再読み込みする必要があります。

多くの WindowsLinux のブラウザ

  • Ctrl を押しながら F5 を押す。

Mac における Safari

  • Shift を押しながら、更新ボタン をクリックする。

Mac における ChromeFirefox

  • Cmd Shift を押しながら R を押す。

詳細についてはWikipedia:キャッシュを消すをご覧ください。

/**
 * saveEditingText.js
 * 編集中のテキストを定期的にローカルストレージに保存
 */

{
  const storageName = 'mwCustomYuukin0248SavedEditText';

  const saveTextToStorage = function (textBox) {
    const storage = mw.storage.getObject(storageName) || {};
    const pageName = mw.config.get('wgPageName');
    const section = mw.util.getParamValue('section') || '*';

    const startSaveInterval = function () {
      console.log('startSaveInterval()');
      // 編集中のテキストを5秒おきにローカルストレージに保存
      setInterval(function () {
        const timestamp = new Date().getTime();
        storage[pageName] = {
          section,
          text: textBox.val(),
          timestamp,
        };
        mw.storage.setObject(storageName, storage);
      }, 5000);
    };

    const data = storage[pageName];

    // 編集中のページのテキストが保存されていて、現在のテキストボックスの内容と異なる
    if (typeof data !== 'undefined' && data.text !== textBox.val()) {
      // 保存されているテキストの節と編集中の節が同じ
      if (data.section === section) {
        new OO.ui.confirm('編集中のページで過去に編集していたテキストが保存されています。編集画面に反映しますか?')
          .then((confirmed) =>
            confirmed ? textBox.val(data.text) : OO.ui.confirm('保存されているテキストを破棄しますか?')
          )
          .then((confirmed) => (confirmed ? removeTextFromStorage() : ''))
          .then(() => startSaveInterval());
        return;
      }

      // 保存されているテキストの節と編集中の節が異なる
      else {
        const params = {
          action: 'parse',
          page: pageName,
          prop: 'wikitext',
          format: 'json',
        };
        // 節編集の場合は section を指定
        if (data.section !== '*') {
          params.section = data.section;
        }

        new mw.Api()
          // API 経由で、保存されているテキストの節のウィキテキストを取得
          .get(params)

          // 保存されているテキストと取得したテキストが一致するか
          .then((res) => res.parse.wikitext['*'].trim() === data.text.trim())

          // matched: 一致で true
          .then(function (matched) {
            // 一致したなら、現在の編集内容を新しく保存し始める
            if (matched) {
              console.log("res.parse.wikitext['*'].trim() !== data.text.trim()", 'true');
              startSaveInterval();
              return 'pass';
            }
            // 一致しなかったなら、保存されているテキストの節へ遷移する確認メッセージを表示
            else {
              console.log("res.parse.wikitext['*'].trim() !== data.text.trim()", 'false');
              return new OO.ui.confirm(
                '編集中のページの他の節で過去に編集していたテキストが保存されています。その節に遷移しますか?'
              );
            }
          })

          // confirmed: true, false, 'pass'
          .then(function (confirmed) {
            // 保存されているテキストと取得したテキストが一致した pass
            if (confirmed === 'pass') return;

            // 保存されているテキストと取得したテキストが一致せず、確認で「はい」を選択した
            if (confirmed) {
              location.href = `?title=${pageName}&action=edit${data.section !== '*' ? '&section=' + data.section : ''}`;
            }
            // 保存されているテキストと取得したテキストが一致せず、確認で「いいえ」を選択した
            else {
              OO.ui.confirm('保存されているテキストを破棄しますか?');
              startSaveInterval();
            }
          });
      }
    }
    // 編集中のページのテキストが保存されていない
    else startSaveInterval();
  };

  const removeTextFromStorage = function () {
    const storage = mw.storage.getObject(storageName) || {};
    const pageName = mw.config.get('wgPageName');

    // 閲覧中のページのテキストを削除
    delete storage[pageName];

    // 最終保存後168時間以上経過したテキストがあればついでに削除
    const sevenDaysAgo = new Date().getTime() - 1000 * 60 * 60 * 24 * 7; // 1000ミリ秒 * 60秒 * 60分 * 24時間 * 7日
    for (const key in storage) {
      if (storage.hasOwnProperty(key)) {
        if (sevenDaysAgo > storage[key].timestamp) {
          delete storage[key];
        }
      }
    }

    // ローカルストレージに保存
    mw.storage.setObject(storageName, storage);
  };

  $.when($.ready, mw.loader.using(['mediawiki.util', 'mediawiki.storage', 'mediawiki.api', 'oojs-ui'])).then(
    function () {
      const wgAction = mw.config.get('wgAction');
      const textBox = $('#wpTextbox1');

      // 編集中であればテキストを保存
      if (wgAction === 'edit' && textBox.length) saveTextToStorage(textBox);
      // 何らかの編集が完了した直後なら、閲覧中のページのテキストを削除
      else if (mw.config.get('wgPostEdit') !== null) removeTextFromStorage();
    }
  );
}