Website Changes Monitor

Automatically tracks and notifies HTML changes on any websites!

当前为 2024-03-28 提交的版本,查看 最新版本

// ==UserScript==
// @name         Website Changes Monitor
// @namespace    https://gf.qytechs.cn/en/users/670188-hacker09?sort=daily_installs
// @version      1
// @description  Automatically tracks and notifies HTML changes on any websites!
// @author       hacker09
// @include      *
// @icon         https://i.imgur.com/0kx5i9q.png
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_listValues
// @grant        GM_deleteValue
// @grant        GM.xmlHttpRequest
// @grant        GM_registerMenuCommand
// @connect      *
// ==/UserScript==

(function() {
  'use strict';
  GM_registerMenuCommand('Add/Remove Website', () => { open('https://f.org/tracker/settings.html', '_blank'); }); //Add a settings button on the Tampermonkey menu

  /* function sortObject(obj) {
    return Object.keys(obj).sort().reduce((sorted, key) => {
        sorted[key] = obj[key];
        return sorted;
    }, {});
} */

  GM_listValues().forEach(function(url) { //For each website on the Tampermonkey storage
    if (url.match(/I_am_a_Dev|^Number$/) === null) //If the current item aren't the variables I_am_a_Dev/Number$
    {
      GM.xmlHttpRequest({ //Start a new xmlHttpRequest
        method: GM_getValue(url, {}).method, //Add the xmlHttpRequest method
        url: url.replace(/Counter\d+/, ''), //Add the xmlHttpRequest method
        headers: GM_getValue(url, {}).header, //Add the xmlHttpRequest header
        data: GM_getValue(url, {}).body, //Add the xmlHttpRequest body
        onload: ({ responseText }) => { //When the xmlHttpRequest is completed
          //if (JSON.stringify(sortObject(GM_getValue(url, {}).HTML)) !== JSON.stringify(sortObject(responseText))) //If the HTML changed
          if (GM_getValue(url, {}).HTML !== responseText) //If the HTML changed
          { //Starts the if condition
            console.table([{'old': GM_getValue(url, {}).HTML, "new": responseText, "if": GM_getValue(url, {}).HTML !== responseText}])
            GM_setValue(url, { "HTML": responseText, "method": GM_getValue(url, {}).method, "header": GM_getValue(url, {}).header, "body": GM_getValue(url, {}).body}); //Add the new HTML on the Tampermonkey storage
            //open(url, '_blank'); //Open the updated website on a new tab
          } //Finishes the if condition
        } //Finishes the onload function
      }); //Finishes the xmlHttpRequest function
    } //Finishes the if condition
  }); //Finishes the function

  //2024 //"action=action_search&vars=%7B%22_wpsearch%22%3A%22ca393a549e%22%2C%22taxonomy%22%3A%22none%22%2C%22search%22%3A%22none%22%2C%22term%22%3A%22none%22%2C%22type%22%3A%22movies%22%2C%22genres%22%3A%5B%5D%2C%22years%22%3A%5B%22113364%22%5D%2C%22sort%22%3A%221%22%2C%22page%22%3A1%7D"

  if (location.href === 'https://f.org/tracker/settings.html') { //If the user is on the page settings website
    document.head.remove(); //Remove the current page head
    document.body.remove(); //Remove the current page body
    document.querySelector("html").innerHTML = `<title>Website Changes Monitor manager</title><style>body { margin: 0; min-width: 250px; } * { box-sizing: border-box; } ul { margin: 0; padding: 0; } ul li { position: relative; padding: 12px 8px 12px 40px; list-style-type: none; background: #eee; font-size: 18px; transition: 0.2s; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } ul li:nth-child(odd) { background: #f9f9f9; } ul li:hover { background: #ddd; } .close { cursor: pointer; position: absolute; right: 0; top: 0; padding: 12px 16px 12px 16px; } .close:hover { background-color: #f44336; color: white; } .header { background-color: #000000; padding: 30px 40px; color: white; text-align: center; } .title { margin: 5px; } .subtitle { text-align: left; } .header:after { content: ""; display: table; clear: both; } .footer { background-color: #000000; padding: 5px 40px; color: white; } input { margin: 0; border: none; border-radius: 0; width: 75%; height: 45px; padding: 10px; float: left; font-size: 16px; } .addBtn { padding: 10px; width: 25%; height: 45px; background: #d9d9d9; color: #555; float: left; text-align: center; font-size: 16px; cursor: pointer; transition: 0.3s; border-radius: 0; } .addBtn:hover { background-color: #bbb; }</style></head><body><div class="header"><h2 class="title">Website Changes Monitor</h2><h3 class="subtitle">Trusted websites:</h3><input type="text" id="Input" placeholder="e.g. reddit.com"><span class="addBtn">Add</span></div><ul id="List"></ul><div class="footer"><h4 class="subtitle">All data is stored in the UserScript's local storage.</h4></div></body> `; //Add the script settings page on the website

    document.getElementsByClassName('addBtn')[0].addEventListener('click', async () => { //If the Add Button is clicked on the page
      GM_getValue("Number") === undefined ? GM_setValue("Number", "Counter1") : GM_setValue("Number", "Counter"+(parseInt(GM_getValue("Number").match(/\d+/)[0]) + 1)); //Create/increase the counter

      GM_getValue("I_am_a_Dev") !== undefined && GM_getValue("I_am_a_Dev").match(/yes|no/) !== null ? '' : GM_setValue("I_am_a_Dev", prompt('OK = Enable advanced developer settings.\nCancel = Simple settings.', 'yes') || 'no'); //Save the user options/data

      if (document.getElementById('Input').value !== '') { //If the user is not trying to add a blank website
        if (GM_getValue("I_am_a_Dev") === 'yes') //If the user is a Dev
        { //Starts the if condition
          var method = prompt('OK = GET request.\nCancel = POST request.', 'GET') || 'POST'; //Ask and save the method
          var header = prompt('OK = Paste the fetch headers.\nCancel = Blank headers.') || '{}'; //Ask and save the header
          var body = prompt('OK = Paste the fetch body/data.\nCancel = Blank body.') || ''; //Ask and save the body
        } //Finishes the if condition

        GM_getValue("I_am_a_Dev") === 'yes' ? GM_setValue(GM_getValue("Number") + `${document.getElementById('Input').value}`, { "HTML": '', "method": method, "header": header !== '{}' ? JSON.parse(header.replace(/\s+/g, ' ').trim()) : '{}', "body": body}) : GM_setValue(GM_getValue("Number") + `${document.getElementById('Input').value}`, { "HTML": '', "method": 'GET', "header": '{}', "body": ''}); //Add the website on the Tampermonkey storage
      } //Finishes the if condition
      await new Promise(resolve => setTimeout(resolve, 2000)); //Wait 1.5 secs to reload
      location.reload(); //Reload the page
    }); //Finishes the onclick function

    GM_listValues().forEach(async function(Storedwebsite) { //For each website on the Tampermonkey storage
      Storedwebsite.match(/I_am_a_Dev|^Number$/) === null ? document.getElementById('List').insertAdjacentHTML('beforeend', `<li>${Storedwebsite.replace(/Counter\d+/, '')}<span class='close'>✘</span></li>`) : ''; //Add the website/close button into the list
      document.querySelector('li:last-child .close')?.addEventListener('click', function() { //When X is clicked
        GM_deleteValue(Storedwebsite); //Remove the website from the Tampermonkey storage
        this.parentElement.style.display = 'none'; //Hide the removed website from the page list
      }); //Finishes the onclick function
    }); //Finishes the function
  } //Finishes the if condition
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址