您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A Tampermonkey script that supports downloading single npm files
- // ==UserScript==
- // @name npm-file-downloader
- // @video https://youtu.be/6BqphFJ69-g
- // @namespace http://tampermonkey.net/
- // @version 2024-11-04
- // @description A Tampermonkey script that supports downloading single npm files
- // @author qer
- // @match https://www.npmjs.com/*
- // @icon https://github.com/user-attachments/assets/7ccadb13-ee47-4206-88bf-050a087988d8
- // @license MIT
- // ==/UserScript==
- (function () {
- 'use strict';
- const mainButtonCssText = `
- background-color: #0969da;
- color: white;
- padding: 8px 16px;
- border: none;
- border-radius: 6px;
- font-size: 14px;
- font-weight: 500;
- cursor: pointer;
- transition: background-color 0.2s ease;
- margin-left: 10px;
- box-shadow: 0 1px 3px rgba(0,0,0,0.12);
- `;
- const downloadButtonCssText = `
- color: #0969da;
- text-decoration: none;
- font-size: 14px;
- padding: 4px 8px;
- border-radius: 4px;
- transition: background-color 0.2s ease;
- `;
- const showDownloadLinksButton = document.createElement('button');
- showDownloadLinksButton.innerHTML = 'Show Download Links';
- showDownloadLinksButton.style.cssText = mainButtonCssText;
- addButtonClickEffect(showDownloadLinksButton);
- showDownloadLinksButton.onclick = showDownloadLinks; // download function
- addShowDownloadLinksButton(); // add button to the page
- function addButtonClickEffect(button) {
- button.addEventListener('mouseover', function () {
- this.style.backgroundColor = '#0557c5';
- });
- button.addEventListener('mouseout', function () {
- this.style.backgroundColor = '#0969da';
- });
- button.addEventListener('mousedown', function () {
- this.style.transform = 'scale(0.98)';
- });
- button.addEventListener('mouseup', function () {
- this.style.transform = 'scale(1)';
- });
- }
- function addShowDownloadLinksButton() {
- const tabListA = document.querySelector('ul[role="tablist"]').querySelectorAll('a');
- if (!tabListA) return;
- for (const a of tabListA) {
- a.onclick = () => {
- if (a.getAttribute('href') === '?activeTab=code') {
- document.querySelector('#main div').childNodes[1].querySelectorAll('li')[1].appendChild(showDownloadLinksButton);
- } else showDownloadLinksButton.remove();
- };
- }
- const link = document.querySelector('a[href="?activeTab=code"]');
- if (!link) return;
- const ariaSelected = link.getAttribute('aria-selected');
- console.log('ariaSelected', ariaSelected);
- if (ariaSelected === 'true') {
- document.querySelector('#main div').childNodes[1].querySelectorAll('li')[1].appendChild(showDownloadLinksButton);
- }
- }
- function info() {
- const path = new URL(window.location.href).pathname.split('/');
- return { packageName: path[2], version: path[4]?.replace(/^v\//, '') || 'latest' };
- }
- function showDownloadLinks() {
- const { packageName, version } = info();
- console.log('Package Name:', packageName);
- console.log('Version:', version);
- const domain = 'https://nfd.qer.im';
- // const domain = 'http://localhost:8787';
- let path = ''; let liElements = [];
- try {
- const section = document.querySelector('#main div').childNodes[2].querySelector('section:not([data-attribute="hidden"])');
- console.log(section);
- path = section.querySelector('h2').innerText.split('/').slice(2)
- .join('/') || '';
- liElements = section.querySelectorAll('ul li');
- if (!liElements || liElements.length <= 0) {
- throw new Error(`Can't find elements: ${path}${liElements.length}`);
- }
- } catch (e) {
- alert(`Failed to add download links: ${e}`);
- }
- liElements.forEach((li, index) => {
- const buttonText = li.querySelector('button').textContent;
- const fileType = li.querySelectorAll('div')[2].textContent;
- // const fileSize = li.querySelectorAll('div')[3].textContent;
- const isFolder = !fileType || fileType.toLowerCase() === 'folder';
- if (buttonText === '../') return;
- const downloadButton = document.createElement('a');
- downloadButton.style.cssText = downloadButtonCssText;
- if (isFolder) {
- downloadButton.textContent = '(Folder)';
- downloadButton.style.cssText += `
- color: #666;
- cursor: not-allowed;
- opacity: 0.7;
- `;
- } else {
- downloadButton.textContent = 'Download';
- downloadButton.style.cursor = 'pointer';
- downloadButton.href = `${domain}/api/download?package=${packageName}&path=${path}&file=${encodeURIComponent(buttonText)}&version=${version}`;
- downloadButton.addEventListener('click', function (event) {
- event.preventDefault();
- const loadingIndicator = document.createElement('span');
- loadingIndicator.textContent = 'Downloading...';
- loadingIndicator.style.marginLeft = '5px';
- this.parentNode.insertBefore(loadingIndicator, this.nextSibling);
- this.style.pointerEvents = 'none';
- this.style.opacity = '0.5';
- setTimeout(() => {
- loadingIndicator.remove();
- this.style.pointerEvents = 'auto';
- this.style.opacity = '1';
- window.location.href = this.href;
- }, 2000);
- });
- }
- const fileNameButton = li.querySelector('button');
- fileNameButton.parentNode.insertBefore(downloadButton, fileNameButton.nextSibling);
- fileNameButton.parentNode.style.display = 'flex';
- fileNameButton.parentNode.style.alignItems = 'center';
- });
- }
- }());
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址