Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Build

on:
push:
branches: [dev, main]
pull_request:
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Resolve artifact name
id: artifact
run: |
VERSION=$(head -n 20 dist/EdgeDL.user.js | grep '@version' | sed -E 's/.*@version\s+([0-9.]+).*/\1/')
SHORT_SHA=$(git rev-parse --short HEAD)

if [ "${{ github.ref_name }}" = "main" ]; then
NAME="EdgeDL-build-v${VERSION}"
else
NAME="EdgeDL-build-v${VERSION}-${SHORT_SHA}"
fi

echo "name=$NAME" >> $GITHUB_OUTPUT

- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: ${{ steps.artifact.outputs.name }}
path: dist/EdgeDL.user.js
87 changes: 59 additions & 28 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,50 +1,81 @@
name: Build & Release
name: Release

on:
workflow_dispatch:
inputs:
publish:
description: '是否创建 Pre-release(dev 分支)'
required: true
default: 'false'
type: choice
options: ['true', 'false']

pull_request:
types: [closed]
branches: [main]

jobs:
build_release:
release:
if: |
github.event_name == 'workflow_dispatch' ||
(
github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.title, 'release:')
)
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
- uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: npm ci
- run: npm ci
- run: npm run build

- name: Resolve version
id: version
run: |
BASE=$(head -n 20 dist/EdgeDL.user.js | grep '@version' | sed -E 's/.*@version\s+([0-9.]+).*/\1/')

if [ "${{ github.ref_name }}" = "dev" ]; then
git fetch --tags
LAST=$(git tag -l "v${BASE}-beta.*" | sort -V | tail -n 1)
if [ -z "$LAST" ]; then
VER="${BASE}-beta.1"
else
N=$(echo "$LAST" | sed -E 's/.*-beta\.([0-9]+)/\1/')
VER="${BASE}-beta.$((N + 1))"
fi
else
VER="$BASE"
fi

- name: Build EdgeDL.user.js
run: npm run build
echo "version=$VER" >> $GITHUB_OUTPUT

- name: Get version and generate release body
id: release_info
- name: Commit dist (main only)
if: github.ref_name == 'main'
run: |
VERSION=$(head -n 20 dist/EdgeDL.user.js | grep '@version' | sed -E 's/.*@version\s+([0-9.]+).*/\1/')
DATE=$(date +%Y-%m-%d)
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "body<<EOF" >> $GITHUB_OUTPUT
echo "## [${VERSION}] - ${DATE}" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "待补" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add dist
git diff --cached --quiet || git commit -m "chore(dist): update build artifacts"
git push origin main

- name: Create GitHub Release
id: create_release
if: |
github.ref_name == 'main' ||
(
github.ref_name == 'dev' &&
github.event_name == 'workflow_dispatch' &&
github.event.inputs.publish == 'true'
)
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.version.outputs.version }}
name: v${{ steps.version.outputs.version }}
files: dist/EdgeDL.user.js
tag_name: v${{ steps.release_info.outputs.version }}
name: v${{ steps.release_info.outputs.version }}
body: ${{ steps.release_info.outputs.body }}
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
prerelease: ${{ github.ref_name == 'dev' }}
340 changes: 0 additions & 340 deletions dist/EdgeDL.user.js

This file was deleted.

4 changes: 2 additions & 2 deletions rollup.config.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 24 additions & 5 deletions src/download-picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,23 @@ export async function showDownloadPicker(url, callback, mode = 'download') {

document.documentElement.appendChild(picker);

const layoutPicker = () => {
const w = window.visualViewport ? visualViewport.width : document.documentElement.clientWidth;
const card = picker.querySelector('.edgedl-card');
if (card) card.style.maxWidth = (w - 32) + 'px';
};
layoutPicker();
if (window.visualViewport) {
visualViewport.addEventListener('resize', layoutPicker);
visualViewport.addEventListener('scroll', layoutPicker);
}

// 注入下载器选择弹窗样式
const style = document.createElement('style');
style.textContent = `
#edgedl-picker { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; z-index: 2147483647; }
#edgedl-picker .edgedl-bg { position: absolute; inset:0; background: rgba(0,0,0,0.45); backdrop-filter: blur(6px); animation: edgedl-fade-in .18s ease-out; }
#edgedl-picker .edgedl-card { position: relative; background: #fff; border-radius: 24px; padding: 20px; width: 260px; box-shadow: 0 10px 28px rgba(0,0,0,0.25); display: flex; flex-direction: column; align-items: center; animation: edgedl-slide-up .22s ease-out; }
#edgedl-picker { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; z-index: 2147483647; pointer-events: none; contain: layout style paint; isolation: isolate; }
#edgedl-picker .edgedl-bg { position: absolute; inset:0; background: rgba(0,0,0,0.45); backdrop-filter: blur(6px); animation: edgedl-fade-in .18s ease-out; pointer-events: auto; }
#edgedl-picker .edgedl-card { position: relative; background: #fff; border-radius: 24px; padding: 20px; width: 260px; max-width: 100%; box-shadow: 0 10px 28px rgba(0,0,0,0.25); display: flex; flex-direction: column; align-items: center; animation: edgedl-slide-up .22s ease-out; pointer-events: auto; box-sizing: border-box; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-weight: 400; line-height: 1.4; -webkit-font-smoothing: antialiased; }
#edgedl-picker h3 { margin: 0 0 16px 0; font-weight: 500; font-size: 16px; }
#edgedl-picker .edgedl-options { display: flex; flex-direction: column; width: 100%; gap: 12px; }
#edgedl-picker .edgedl-options button { display: flex; align-items: center; gap: 10px; padding: 10px; border: none; border-radius: 12px; background: #f2f2f2; font-weight: 500; cursor: pointer; transition: background 0.2s; }
Expand Down Expand Up @@ -97,7 +108,7 @@ export async function showDownloadPicker(url, callback, mode = 'download') {
`;
document.head.appendChild(style);

// 读取默认下载器(GM 储存)
// 读取默认下载器
const defaultDownloader = await GM_getValue(DEFAULT_KEY, null);
const defaultCheckbox = picker.querySelector('#edgedl-set-default');

Expand Down Expand Up @@ -156,6 +167,10 @@ export async function showDownloadPicker(url, callback, mode = 'download') {

picker.classList.add('closing');
picker.addEventListener('animationend', () => {
if (window.visualViewport) {
visualViewport.removeEventListener('resize', layoutPicker);
visualViewport.removeEventListener('scroll', layoutPicker);
}
picker.remove();
style.remove();
window.dispatchEvent(new CustomEvent('edgedl:picker-closed'));
Expand All @@ -168,9 +183,13 @@ export async function showDownloadPicker(url, callback, mode = 'download') {
picker.querySelector('.edgedl-bg').addEventListener('click', () => {
picker.classList.add('closing');
picker.addEventListener('animationend', () => {
if (window.visualViewport) {
visualViewport.removeEventListener('resize', layoutPicker);
visualViewport.removeEventListener('scroll', layoutPicker);
}
picker.remove();
style.remove();
window.dispatchEvent(new CustomEvent('edgedl:picker-closed'));
}, { once: true });
});
}
}
3 changes: 3 additions & 0 deletions src/intent/adm.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ export async function openADM(url) {
const cleanLink = url.replace(/^https?:\/\//, '');
const intentUrl = `intent://${cleanLink}#Intent;scheme=${scheme};package=${DOWNLOADERS.ADM};type=*/*;end`;
window.location.href = intentUrl;
setTimeout(() => {
window.location.href = intentUrl;
}, 200);
}
2 changes: 1 addition & 1 deletion src/intent/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export async function openDownload(url, downloader) {
case 'edge':
default:
showToast('⚡ Edge 内置下载');
window.open(url, '_blank');
GM_download({ url, saveAs: false });
break;
}
}
41 changes: 24 additions & 17 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,36 @@ import { showDownloadPicker } from './download-picker.js';
import { registerMenu } from './menu.js';
registerMenu();

// 获取当前默认下载器
// 读取默认下载器配置
function getDefaultDownloader() {
return GM_getValue('edgedl-default-downloader');
}

// 全局点击拦截下载
// 拦截点击事件并接管下载
document.addEventListener('click', e => {
let target = e.target;
while (target && target.tagName !== 'A') target = target.parentElement;
if (!target) return;
if (e.defaultPrevented) return;

const url = target.href;
if (isDownloadLink(url)) {
e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
if (e.__edgedl_handled__) return;
e.__edgedl_handled__ = true;

const defaultDownloader = getDefaultDownloader();
if (defaultDownloader) {
openDownload(url, defaultDownloader);
} else {
// 弹出下载选择器
showDownloadPicker(url, selected => {
openDownload(url, selected);
});
}
const link = e.target?.closest?.('a');
if (!link || !link.href) return;

const url = link.href;
if (!isDownloadLink(url)) return;

// 阻止浏览器原生下载与页面跳转
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();

const defaultDownloader = getDefaultDownloader();
if (defaultDownloader) {
openDownload(url, defaultDownloader);
} else {
// 无默认配置时弹出下载器选择
showDownloadPicker(url, selected => {
openDownload(url, selected);
});
}
}, true);