├── public ├── icons │ ├── icon-128.png │ ├── icon-16.png │ ├── icon-32.png │ ├── icon-48.png │ └── icon-96.png ├── popup │ └── index.html └── options │ └── index.html ├── .gitignore ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── src ├── inject.ts ├── content │ ├── utils │ │ ├── dom.ts │ │ ├── zip.ts │ │ └── fn.ts │ ├── threads │ │ ├── button.ts │ │ ├── index.ts │ │ └── post.ts │ ├── profile.ts │ ├── reels.ts │ ├── highlights.ts │ ├── post-detail.ts │ ├── stories.ts │ ├── post.ts │ ├── profile-reel.ts │ ├── button.ts │ └── index.ts ├── constants.ts ├── popup │ ├── SettingItem.tsx │ ├── index.scss │ └── index.tsx ├── options │ ├── index.ts │ └── index.scss ├── manifest.firefox.json ├── manifest.chrome.json ├── types │ ├── profileReel.d.ts │ ├── stories.d.ts │ ├── reels.d.ts │ ├── highlights.d.ts │ └── global.d.ts ├── background │ ├── fn.ts │ ├── chrome.ts │ └── firefox.ts └── xhr.ts ├── tsconfig.json ├── LICENSE ├── eslint.config.js ├── README.md ├── esbuild.config.mjs └── package.json /public/icons/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKonka/instagram-download-browser-extension/HEAD/public/icons/icon-128.png -------------------------------------------------------------------------------- /public/icons/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKonka/instagram-download-browser-extension/HEAD/public/icons/icon-16.png -------------------------------------------------------------------------------- /public/icons/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKonka/instagram-download-browser-extension/HEAD/public/icons/icon-32.png -------------------------------------------------------------------------------- /public/icons/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKonka/instagram-download-browser-extension/HEAD/public/icons/icon-48.png -------------------------------------------------------------------------------- /public/icons/icon-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheKonka/instagram-download-browser-extension/HEAD/public/icons/icon-96.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | **/.DS_Store 4 | yarn-error.log 5 | .idea 6 | .vscode 7 | yarn.lock 8 | package-lock.json 9 | 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | Browser(Chrome/Firefox/Firefox for Android): 10 | Extension Version: 11 | Reproduction of links: 12 | -------------------------------------------------------------------------------- /src/inject.ts: -------------------------------------------------------------------------------- 1 | const script = document.createElement('script'); 2 | script.setAttribute('type', 'text/javascript'); 3 | script.setAttribute('src', chrome.runtime.getURL('xhr.js')); 4 | script.onload = () => { 5 | script.remove(); 6 | }; 7 | (document.head || document.documentElement).appendChild(script); 8 | -------------------------------------------------------------------------------- /public/popup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/content/utils/dom.ts: -------------------------------------------------------------------------------- 1 | export function getParentArticleNode(node: HTMLElement | null) { 2 | if (node === null) return null; 3 | if (node.tagName === 'ARTICLE') { 4 | return node; 5 | } 6 | return getParentArticleNode(node.parentElement); 7 | } 8 | 9 | export function getParentSectionNode(node: HTMLElement | null) { 10 | if (node === null) return null; 11 | if (node.tagName === 'SECTION') { 12 | return node; 13 | } 14 | return getParentSectionNode(node.parentElement); 15 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "module": "preserve", 5 | "noEmit": true, 6 | "target": "ESNext", 7 | "lib": ["es2022", "dom", "dom.iterable"], 8 | // "sourceMap": true, 9 | // "rootDir": "./src", 10 | "jsx": "react-jsx", 11 | "downlevelIteration": true, 12 | "noEmitOnError": true, 13 | "allowJs": true, 14 | "skipLibCheck": true, 15 | "allowSyntheticDefaultImports": true, 16 | "types": ["chrome-types", "firefox-webext-browser"] 17 | }, 18 | "exclude": ["node_modules", "public", "dist", "./src/*.js", "*.js"] 19 | } 20 | -------------------------------------------------------------------------------- /src/content/threads/button.ts: -------------------------------------------------------------------------------- 1 | import { handleThreadsPost } from './post'; 2 | 3 | function findContainerNode(target: HTMLAnchorElement) { 4 | let node = target.parentElement; 5 | while (node && node.getAttribute('data-pressable-container') !== 'true') { 6 | node = node.parentElement; 7 | } 8 | return node; 9 | } 10 | 11 | export function handleThreadsButton(target: HTMLAnchorElement) { 12 | const action = target.className.includes('download-btn') ? 'download' : 'open'; 13 | const container = findContainerNode(target); 14 | 15 | if (container instanceof HTMLDivElement) { 16 | handleThreadsPost(container, action); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const CONFIG_LIST = [ 2 | 'setting_show_open_in_new_tab_icon', 3 | 'setting_show_zip_download_icon', 4 | 'setting_enable_threads', 5 | 'setting_enable_video_controls', 6 | 'setting_format_replace_jpeg_with_jpg', 7 | 'setting_format_use_hash_id', 8 | 'setting_format_use_indexing', 9 | 'setting_enable_datetime_format', 10 | ]; 11 | 12 | export const DEFAULT_FILENAME_FORMAT = `{username}-{datetime}-{id}`; 13 | export const DEFAULT_DATETIME_FORMAT = 'YYYYMMDD_HHmmss'; 14 | 15 | export const EXTENSION_ID = 'oejjpeobjicdpgaijialfpfcbdnanajk'; 16 | 17 | export const CLASS_CUSTOM_BUTTON = 'custom-btn'; 18 | 19 | 20 | export const MESSAGE_OPEN_URL = "open_url" 21 | export const MESSAGE_ZIP_DOWNLOAD = "zip_download" -------------------------------------------------------------------------------- /src/popup/SettingItem.tsx: -------------------------------------------------------------------------------- 1 | const SettingItem: React.FC<{ 2 | value: boolean; 3 | setValue: React.DispatchFor more options, please open the popup by clicking the extension's action icon.
29 | 30 |34 | See 35 | Source code on Github 38 |
39 |Please consider starring the project to show your ❤️ and support.
40 | 41 |Copyright 2025
42 |