更新日:

プチリリ歌詞コピー Chrome拡張

manifest.json
{
  "name": "プチリリ歌詞コピー",
  "version": "1.0.0",
  "manifest_version": 3,
  "description": "プチリリ歌詞コピー",
  "content_scripts": [
    {
      "matches": ["https://petitlyrics.com/lyrics/*"],
      "js": ["./base64.js", "./app.js"]
    }
  ]
}
app.js
const main = () => {
  const div = document.createElement('div');
  const button = document.createElement('button');
  div.appendChild(button);
  document.querySelector('.title-bar').previousElementSibling.after(div);

  div.style.textAlign = 'center';

  button.textContent = '歌詞をコピーする';
  button.style.width = '150px';
  button.style.height = '50px';

  button.onclick = async () => {
    if (!navigator.clipboard) {
      return;
    }

    let res = await fetch('https://petitlyrics.com/lib/pl-lib.js', {
      credentials: 'include',
    });

    const csrf_token = (await res.text())
      .split('\n')[2]
      .split(',')[1]
      .replace('"', '')
      .replace("'", '')
      .replace("'", '')
      .replace(')', '')
      .replace(';', '');

    res = await fetch('/com/get_lyrics.ajax', {
      method: 'POST',
      credentials: 'include',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-Token': csrf_token,
      },
      body: `lyrics_id=${Number(location.pathname.split('/')[2])}`,
    });

    const data = await res.json();
    const len = data.length;
    let text = '';
    for (let i = 0; i < len; i++) {
      text += Base64.decode(data[i].lyrics);
      text += '\n';
    }

    navigator.clipboard.writeText(text);
    alert('歌詞をコピーしました');
  };
};

main();
base64.js
/*
 * $Id: base64.js,v 2.11 2013/04/08 12:27:14 dankogai Exp dankogai $
 *
 *  Licensed under the MIT license.
 *    http://opensource.org/licenses/mit-license
 *
 *  References:
 *    http://en.wikipedia.org/wiki/Base64
 */

(function (global) {
  'use strict';
  if (global.Base64) return;
  var version = '2.1.1';
  // if node.js, we use Buffer
  var buffer;
  if (typeof module !== 'undefined' && module.exports) {
    buffer = require('buffer').Buffer;
  }
  // constants
  var b64chars =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  var b64tab = (function (bin) {
    var t = {};
    for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
    return t;
  })(b64chars);
  var fromCharCode = String.fromCharCode;
  // encoder stuff
  var cb_utob = function (c) {
    if (c.length < 2) {
      var cc = c.charCodeAt(0);
      return cc < 0x80
        ? c
        : cc < 0x800
        ? fromCharCode(0xc0 | (cc >>> 6)) + fromCharCode(0x80 | (cc & 0x3f))
        : fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) +
          fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) +
          fromCharCode(0x80 | (cc & 0x3f));
    } else {
      var cc =
        0x10000 +
        (c.charCodeAt(0) - 0xd800) * 0x400 +
        (c.charCodeAt(1) - 0xdc00);
      return (
        fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) +
        fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) +
        fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) +
        fromCharCode(0x80 | (cc & 0x3f))
      );
    }
  };
  var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
  var utob = function (u) {
    return u.replace(re_utob, cb_utob);
  };
  var cb_encode = function (ccc) {
    var padlen = [0, 2, 1][ccc.length % 3],
      ord =
        (ccc.charCodeAt(0) << 16) |
        ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8) |
        (ccc.length > 2 ? ccc.charCodeAt(2) : 0),
      chars = [
        b64chars.charAt(ord >>> 18),
        b64chars.charAt((ord >>> 12) & 63),
        padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
        padlen >= 1 ? '=' : b64chars.charAt(ord & 63),
      ];
    return chars.join('');
  };
  var btoa =
    global.btoa ||
    function (b) {
      return b.replace(/[\s\S]{1,3}/g, cb_encode);
    };
  var _encode = buffer
    ? function (u) {
        return new buffer(u).toString('base64');
      }
    : function (u) {
        return btoa(utob(u));
      };
  var encode = function (u, urisafe) {
    return !urisafe
      ? _encode(u)
      : _encode(u)
          .replace(/[+\/]/g, function (m0) {
            return m0 == '+' ? '-' : '_';
          })
          .replace(/=/g, '');
  };
  var encodeURI = function (u) {
    return encode(u, true);
  };
  // decoder stuff
  var re_btou = new RegExp(
    [
      '[\xC0-\xDF][\x80-\xBF]',
      '[\xE0-\xEF][\x80-\xBF]{2}',
      '[\xF0-\xF7][\x80-\xBF]{3}',
    ].join('|'),
    'g'
  );
  var cb_btou = function (cccc) {
    switch (cccc.length) {
      case 4:
        var cp =
            ((0x07 & cccc.charCodeAt(0)) << 18) |
            ((0x3f & cccc.charCodeAt(1)) << 12) |
            ((0x3f & cccc.charCodeAt(2)) << 6) |
            (0x3f & cccc.charCodeAt(3)),
          offset = cp - 0x10000;
        return (
          fromCharCode((offset >>> 10) + 0xd800) +
          fromCharCode((offset & 0x3ff) + 0xdc00)
        );
      case 3:
        return fromCharCode(
          ((0x0f & cccc.charCodeAt(0)) << 12) |
            ((0x3f & cccc.charCodeAt(1)) << 6) |
            (0x3f & cccc.charCodeAt(2))
        );
      default:
        return fromCharCode(
          ((0x1f & cccc.charCodeAt(0)) << 6) | (0x3f & cccc.charCodeAt(1))
        );
    }
  };
  var btou = function (b) {
    return b.replace(re_btou, cb_btou);
  };
  var cb_decode = function (cccc) {
    var len = cccc.length,
      padlen = len % 4,
      n =
        (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0) |
        (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0) |
        (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0) |
        (len > 3 ? b64tab[cccc.charAt(3)] : 0),
      chars = [
        fromCharCode(n >>> 16),
        fromCharCode((n >>> 8) & 0xff),
        fromCharCode(n & 0xff),
      ];
    chars.length -= [0, 0, 2, 1][padlen];
    return chars.join('');
  };
  var atob =
    global.atob ||
    function (a) {
      return a.replace(/[\s\S]{1,4}/g, cb_decode);
    };
  var _decode = buffer
    ? function (a) {
        return new buffer(a, 'base64').toString();
      }
    : function (a) {
        return btou(atob(a));
      };
  var decode = function (a) {
    return _decode(
      a
        .replace(/[-_]/g, function (m0) {
          return m0 == '-' ? '+' : '/';
        })
        .replace(/[^A-Za-z0-9\+\/]/g, '')
    );
  };
  // export Base64
  global.Base64 = {
    VERSION: version,
    atob: atob,
    btoa: btoa,
    fromBase64: decode,
    toBase64: encode,
    utob: utob,
    encode: encode,
    encodeURI: encodeURI,
    btou: btou,
    decode: decode,
  };
  // if ES5 is available, make Base64.extendString() available
  if (typeof Object.defineProperty === 'function') {
    var noEnum = function (v) {
      return {
        value: v,
        enumerable: false,
        writable: true,
        configurable: true,
      };
    };
    global.Base64.extendString = function () {
      Object.defineProperty(
        String.prototype,
        'fromBase64',
        noEnum(function () {
          return decode(this);
        })
      );
      Object.defineProperty(
        String.prototype,
        'toBase64',
        noEnum(function (urisafe) {
          return encode(this, urisafe);
        })
      );
      Object.defineProperty(
        String.prototype,
        'toBase64URI',
        noEnum(function () {
          return encode(this, true);
        })
      );
    };
  }
  // that's it!
})(this);

関連

歌ネット歌詞コピーページ

UtaTenコピーページ

うたまっぷコピーページ

J-Lyric.netコピーページ

歌ネット歌詞コピー Chrome拡張

UtaTen歌詞コピー Chrome拡張

うたまっぷ歌詞コピー Chrome拡張

J-Lyric.net歌詞コピー Chrome拡張

プチリリ歌詞コピー Chrome拡張