Console Importer
// ==UserScript==
// @name Console Importer
// @name:en Console Importer
// @description 通过控制台导入 JS / CSS 库
// @description:en Import JavaScript or CSS Library in browser developer tool.
// @author Yiero
// @version 1.2.0
// @match https://*/*
// @license GPL
// @icon https://bbs.tampermonkey.net.cn/favicon.ico
// @run-at document-body
// @grant GM_addElement
// @grant GM_xmlhttpRequest
// @namespace https://github.com/AliubYiero/TamperMonkeyScripts/
// @connect cdnjs.cloudflare.com
// @connect cdn.bootcdn.net
// @connect api.bootcdn.cn
// @connect cdn.jsdelivr.net
// ==/UserScript==
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
enumerable: true,
configurable: true,
writable: true,
value: value
}) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
class Info {
constructor(projectName) {
__publicField(this, "projectName");
__publicField(this, "header");
this.projectName = projectName;
this.header = `[${projectName}]`;
}
log(...msg) {
(() => {})(...this.contentInfo(...msg));
}
info(...msg) {
console.info(...this.contentInfo(...msg));
}
warn(...msg) {
console.warn(...this.contentInfo(...msg));
}
error(...msg) {
console.error(...this.contentInfo(...msg));
}
group() {
console.group(this.header);
}
groupEnd() {
console.groupEnd();
}
contentInfo(...msg) {
return [ this.header, ...msg ];
}
}
function isCSS(url) {
return url.endsWith("css");
}
const urlList = new Map;
function GMHttpRequest(url, method = "GET", paramOrData, GMXmlHttpRequestConfig = {}) {
if (paramOrData && method === "GET") {
const params = [];
for (const key in paramOrData) {
if (Object.hasOwnProperty.call(paramOrData, key)) {
const value = paramOrData[key];
params.push(`${key}=${JSON.stringify(value)}`);
}
}
url += `?${params.join("?")}`;
} else if (paramOrData && method === "POST") {
GMXmlHttpRequestConfig.data = {
...paramOrData
};
}
return new Promise(((resolve, reject) => {
const newGMXmlHttpRequestConfig = {
timeout: 2e4,
...GMXmlHttpRequestConfig,
url: url,
method: method,
onload(response) {
resolve(response);
},
onerror(error) {
reject(error);
}
};
GM_xmlhttpRequest(newGMXmlHttpRequestConfig);
}));
}
const api_Bootcdn = async searchLibrary => {
const bootcdnApiDetailDomain = "https://api.bootcdn.cn/libraries/";
const bootcdnApiDomain = "https://cdn.bootcdn.net/ajax/libs/";
const res = await GMHttpRequest(bootcdnApiDetailDomain + searchLibrary);
let link = "";
if (res.status !== 200) {
return Promise.reject("Can not find library from bootcdn...");
} else {
const response = JSON.parse(res.response);
const {filename: filename, version: version} = response[0];
link = `${bootcdnApiDomain}/${searchLibrary}/${version}/${filename}`;
print.log("\u4ece bootcdn \u4e2d\u67e5\u627e\u5230\u5e93: ", link);
return Promise.resolve(link);
}
};
async function getBootcdnLibrary(searchLibrary) {
const reSearchLibrary = searchLibrary.endsWith(".js") ? searchLibrary.replace(".js", "") : searchLibrary + ".js";
const searchLibraryList = [ searchLibrary, reSearchLibrary, searchLibrary.toLowerCase(), reSearchLibrary.toLowerCase() ];
for (let i = 0; i < searchLibraryList.length; i++) {
const searchLibrary2 = searchLibraryList[i];
print.warn("\u6b63\u5728\u5c1d\u8bd5\u4ece bootcdn \u4e2d\u83b7\u53d6\u5e93: ", searchLibrary2);
let link = "";
try {
link = await api_Bootcdn(searchLibrary2);
} catch (e) {
print.error("\u83b7\u53d6\u5e93\u5931\u8d25: ", searchLibrary2);
}
if (link.startsWith("http")) {
return link;
}
}
print.error("\u65e0\u6cd5\u4ece bootcdn \u4e2d\u83b7\u53d6\u5230\u5e93: ", searchLibrary);
throw new Error(`Can not found library from bootcdn: ${searchLibrary}`);
}
async function getUrl(urlOrLibrary) {
let url;
if (urlOrLibrary.startsWith("https")) {
url = urlOrLibrary;
} else {
url = await getBootcdnLibrary(urlOrLibrary);
}
return url;
}
async function installLibrary(urlOrLibrary) {
print.group();
const url = await getUrl(urlOrLibrary);
if (urlList.has(url)) {
print.error(`\u83b7\u53d6\u6570\u636e\u5931\u8d25...\n\u5f53\u524d\u9875\u9762\u4e2d\u5df2\u5b58\u5728\u5e93 [${url}]`);
print.groupEnd();
return;
}
print.info("\u6b63\u5728\u52a0\u8f7d\u6570\u636e...");
GMHttpRequest(url).then((res => {
if (res.status === 404) {
print.error(`\u83b7\u53d6\u6570\u636e\u5931\u8d25...\nError: page not found, request an error url: ${url}`);
print.groupEnd();
return;
} else if (res.status !== 200) {
print.error(`\u83b7\u53d6\u6570\u636e\u5931\u8d25...\nError: ${res.responseText}`);
print.groupEnd();
return;
}
const scriptText = res.responseText;
const isScript = !isCSS(url);
const displayObj = {
tag: isScript ? "script" : "style",
content: isScript ? "\u811a\u672c" : "\u6837\u5f0f\u8868"
};
print.info(`\u6210\u529f\u83b7\u53d6${displayObj.content}, \u6b63\u5728\u8f7d\u5165\u9875\u9762...`);
const element = GM_addElement(document.head, displayObj.tag, {
textContent: scriptText
});
urlList.set(url, element);
print.info(`${displayObj.content}\u8f7d\u5165\u6210\u529f.\n${url}`);
print.groupEnd();
}), (error => {
print.error("\u83b7\u53d6\u6570\u636e\u5931\u8d25...\nError: ", error.error);
print.groupEnd();
}));
}
async function uninstallLibrary(url) {
print.group();
const element = urlList.get(await getUrl(url));
if (!element) {
print.warn("\u5f53\u524d\u9875\u9762\u672a\u5b89\u88c5\u5e93: \n", url);
print.groupEnd();
return;
}
element == null ? void 0 : element.remove();
print.info(`\u5f53\u524d\u5e93\u5df2\u5220\u9664: \n`, url);
urlList.delete(url);
print.groupEnd();
}
const print = new Info("Console Importer");
(() => {
unsafeWindow.$i = installLibrary;
unsafeWindow.$o = getBootcdnLibrary;
unsafeWindow.$ui = uninstallLibrary;
})();