libloader

none

اعتبارا من 19-04-2024. شاهد أحدث إصدار.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

ستحتاج إلى تثبيت إضافة مثل Stylus لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتتمكن من تثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

(لدي بالفعل مثبت أنماط للمستخدم، دعني أقم بتثبيته!)

// ==UserScript==
// @name         libloader
// @version      2
// @description  none
// @license      GPLv3
// @run-at       document-start
// @author       You
// @match        *://*/*
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAAAXNSR0IB2cksfwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAHJQTFRFAAAAEIijAo2yAI60BYyuF4WaFIifAY6zBI2wB4usGIaZEYigIoiZCIyrE4igG4iYD4mjEomhFoedCoqpDIqnDomlBYyvE4efEYmiDYqlA42xBoytD4mkCYqqGYSUFYidC4qoC4upAo6yCoupDYqmCYur4zowOQAAACZ0Uk5TAO////9vr////1+/D/+/L+/Pf/////+f3///////H4////////+5G91rAAACgUlEQVR4nM2Y22KjIBCGidg1264liZqDadK03X3/V2wNKHMC7MpF/xthHD5mgERAqZhWhfYqH6K+Qf2qNNf625hCoFj9/gblMUi5q5jLkXLCKudgyiRm0FMK82cWJp1fLbV5VmvJbCIc0GCYaFqqlDJgADdBjncqAXYobm1xh72aFMflbysteFfdy2Yi1XGOm5HGBzQ1dq7TzEoxjeNTjQZb7VA3e1c7+ImgasAgQ9+xusNVNZIo5xmOMgihIS2PbCQIiHEUdTvhxCcS/kPomfFI2zHy2PkWmA6aNatIJpKFJyekyy02xh5Y3DI9T4aOT6VhIUrsNTFp1pf79Z4SIIVDegl6IJO6cHiL/GimIZDhgTu/BlYWCQzHMl0zBWT/T3KAhtxOuUB9FtBrpsz0RV4xsjHmW+UCaffcSy/5viMGer0/6HdFNMZBq/vjJL38H9Dqx4Fuy0Em12DbZy+9pGtiDijbglwAehyj11n0tRD3WUBm+lwulE/8h4BuA+iWAQQnteg2Xm63WQLTpnMnpjdge0Mgu/GRPsV4xdjQ94Lfi624fabhDkfUqIKNrM64Q837v8yL0prasepCgrtvw1sJpoqanGEX7b5mQboNW8eawXaWXTMfMGxub472hzWzHSn6Sg2G9+6TAyRruE71s+zAzjWaknoyJCQzwxrghH2k5FDT4eqWunuNxyN9QCGcxVod5oADbYnIUkDTGZEf1xDJnSFteQ3KdsT8zYDMQXcHxsevcLH1TrsABzkNPyA/L7b0jg704viMMlpQI96WsHknCt/3YH0kOEo9zcGkwrFK39ck72rmoehmKqo2RKlilzSy/nJKEV45CT38myJp456fezktHjN5aeMAAAAASUVORK5CYII=
// @namespace https://greasyfork.org/users/1184528
// @require https://update.greasyfork.org/scripts/491829/1356221/tampermonkey%20storage%20proxy.js
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// ==/UserScript==
JSON.tryparse ??= function (...args) {
  try {
    return JSON.parse(...args)
  } catch (e) {
    console.warn("JSON.tryparse error", e)
    return undefined
  }
}
;(async () => {
  var err
  var optionsmenu
  var userliboptions = {}
  var sp
  var usels = false
  const loadedscripts = {
    libloader: {
      savelib,
      loadlib,
      waitforlib,
      //       requirescript, //for saying that a certan script should've been loaded by the time this function was called
    },
  }
  var menus = []
  try {
    try {
      sp = new storageproxy("globaloptions")
      userliboptions = sp.get()
      //       unsafeWindow.sp = sp
    } catch (e) {
      usels = true
      userliboptions = JSON.tryparse(localStorage.libloaderuseroptions) ?? {}
    }
    waitforlib("strict").then(() => {
      waitforlib("menu").then(() => {
        optionsmenu = loadlib("menu")
        menus = menus.map(tomenu)
        //         warn(menus)
        menus.forEach(({ name, menu }) => {
          if (sp)
            GM_registerMenuCommand(
              `lib options: ${name}`,
              () => {
                userliboptions = sp.get()
                menu.show()
              },
              {
                accessKey: userliboptions[name].accessKey,
              }
            )
          else menu //.show()
        })
      })
    })
  } catch (e) {
    console.error(e)
  }
  function tomenu(menu) {
    return {
      name: menu[0],
      menu: new optionsmenu(userliboptions[menu[0]], formatformat(menu), {
        noclosebutton: false,
        position:'unset',
        onchange: usels
          ? function (...a) {
              log(...a)
              localStorage.libloaderuseroptions = JSON.stringify(userliboptions)
            }
          : log,
      }),
    }
  }
  async function waitforlib(name) {
    return new Promise((done) => {
      var int = setInterval(() => {
        if (name in loadedscripts) return done(clearInterval(int))
      })
    })
  }
  function loadlib(name, filename = "unset") {
    // if (err) throw new Error(err)
    name = name.replace(/\.js$/, "")
    if (!loadedscripts[name]) {
      err ??= `{${filename}} script "${name}" hasn't been loaded`
      log({ ...loadedscripts }, loadedscripts)
      throw new Error(err)
    }
    return loadedscripts[name]
  }
  //   function getfilename() {
  //     var scripts = document.getElementsByTagName("script")
  //     var src = scripts[scripts.length - 1].src
  //     src = src.replaceAll(/%\d\d/g, "")
  //     if (src.startsWith("blob:")) return src.match(/[\w\d._]+\.js(?!\w)/)[0]
  //     return src.match(/\/[^\/]\.js$/)[0]
  //   }

  function savelib(name, obj, liboptions, filename) {
    filename ??= name
    name = name.replace(/\.js$/, "")
    if (Object.prototype.toString.call(obj) === "[object Object]") {
      if (!loadedscripts[name]) loadedscripts[name] = {}
      Object.assign(loadedscripts[name], obj)
    } else {
      if (loadedscripts[name]) {
        if (
          Object.prototype.toString.call(loadedscripts[name]) ===
          "[object Object]"
        ) {
          err ??= `{${filename}} script with name "${name}" was allready loaded as an object`
          throw new Error(err)
        } else {
          err ??= `{${filename}} script with name "${name}" was allready loaded`
          throw new Error(err)
        }
      }
      loadedscripts[name] = obj
      if (liboptions) {
        var temp = {}
        Object.entries(liboptions).forEach(([key, val]) => {
          if (!("default" in liboptions[key]))
            throw new Error(`default ${name} ${key} is missing default peram`)
          temp[key] = val.default
          //           delete liboptions[key].default
        })
        userliboptions[name] = {
          ...temp,
          ...(userliboptions[name] ?? {}),
        }
        //         if (sp)
        log(liboptions)
        liboptions = {
          ...liboptions,
          accessKey: {
            type: "key",
            keyreturntype: "string",
            allowmodifiers: false,
            ignorekeycase: true,
          },
        }
        if (optionsmenu) {
          menus.push(tomenu(liboptions))
        } else {
          menus.push([name, liboptions])
        }
      }
      if (userliboptions[name]) {
        return new Proxy(userliboptions[name], {
          get(_obj, prop) {
            if (prop == "accessKey") return undefined
            if (sp) userliboptions = sp.get()
            if (prop in liboptions) return Reflect.get(_obj, prop)
            else throw new Error(`no default set for user option ${prop}`)
          },
          set() {},
          deleteProperty() {},
        })
      }
    }
  }
  function formatformat([name, obj]) {
    var newobj = []
    Object.entries(obj).forEach(([key, val]) => {
      newobj.push({ text: key, ...loadlib("strict").setformat(val), key })
    })
    newobj.push({
      text: "copy settings object",
      type: "button",
      buttontext: "copy",
      onclick() {
        navigator.clipboard.writeText(JSON.stringify(userliboptions))
      },
    })
    return newobj
  }
  Object.assign(sp ? unsafeWindow : window, {
    loadlib,
  })
})()