Skip to content

Commit

Permalink
Enhance performance by blocking image loading in background tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
hppanpaliya committed Jan 6, 2025
1 parent 90c0965 commit 1139df1
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 34 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Changelog

## [2.5] - January 5, 2025

- **Enhancement:** Improved performance by blocking image loading in background tabs
- Faster page loading during order collection and invoice download
- Reduced network usage

## [2.4] - January 5, 2025

- **Enhancement:**
Feature: Added comprehensive FAQ page with troubleshooting guides
- **Enhancement:** Feature: Added comprehensive FAQ page with troubleshooting guides
- Step-by-step instructions for single and batch downloads
- Chrome settings configuration guide for bulk downloads
- Common issues and solutions
Expand Down
108 changes: 82 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,47 @@
# Walmart Invoice Exporter

A Chrome extension that allows users to download their Walmart order history in XLSX format. Now with support for batch downloading multiple orders!
A Chrome extension that allows users to download their Walmart order history in XLSX format. Now with enhanced performance and optimized batch downloading capabilities!

<img src="./screenshot.png" alt="Screenshot of extension" height="200">
<img src="./screenshot.webp" alt="Screenshot of extension" height="200">

## Features

- **Batch Download**: Select and download multiple order invoices at once
- **Page Crawling**: Automatically collect order numbers from your order history
- **Smart Image Blocking**: Automatically blocks images during processing to improve speed
- **Customizable Limits**: Set how many pages of order history to crawl
- **Detailed Excel Format**: Each invoice includes:
- Product details (name, quantity, price)
- Delivery status
- Product links
- Order information (number, date)
- Additional charges (delivery, tax, tip)
- **Secure**: Runs only on Walmart's orders pages with minimal required permissions
- **Secure & Efficient**: Runs only on Walmart's orders pages with minimal required permissions

## Technical Details

- Uses Chrome's Manifest V3
- Requires `ActiveTabs` permission
- Compatible with various Walmart order formats:
- Regular orders (13 or 15 digits)
- In-store purchases (20+ digits)
- Implements ExcelJS for XLSX generation
- Features smart image blocking for performance
- Handles bulk downloads with proper throttling

## Performance Features

- **Image Blocking**: Automatically prevents image loading to speed up page processing
- **Memory Optimization**: Cleans up resources after each order download
- **Background Processing**: Efficient handling of multiple downloads
- **Smart Retries**: Automatically attempts different URL formats for failed downloads

## Limitations

- Works only on Walmart's order pages
- Download speed may vary based on network conditions
- Large batch downloads may take several minutes to complete
- Requires stable and fast internet connection for bulk downloads

## Installation

Expand All @@ -31,6 +57,9 @@ Install the Walmart Invoice Exporter directly from the [Chrome Web Store](https:
4. Click "Load unpacked" and select the extension directory
5. Pin the extension to your toolbar for easy access

## What's New
### [Changelog](./CHANGELOG.md)

## Usage

### Single Order Download
Expand All @@ -48,40 +77,62 @@ Install the Walmart Invoice Exporter directly from the [Chrome Web Store](https:
5. Wait for the order numbers to load (may take a few seconds)
6. Select the orders you want to download
7. Click "Download Selected Orders"
8. Wait for the download to complete (may take a few minutes)
8. Wait for the downloads to complete

## What's New in Version 2.0

- **Multiple Order Downloads**: Download several orders at once
- **Order History Crawler**: Automatically collect order numbers from your history
- **Improved UI**: New interface with progress tracking and order selection
- **Enhanced Extraction**: Better handling of different order number formats
- **Background Processing**: Smoother download handling with background operations

## Technical Details
## Troubleshooting

- Uses Chrome's Manifest V3
- Requires `tabs` permission for batch processing
- Compatible with various Walmart order formats:
- Regular orders (13 or 15 digits)
- In-store purchases (20 digits)
- Implements ExcelJS for XLSX generation
- Handles concurrent downloads with proper throttling
### Required Chrome Settings for Downloads

## Limitations
Before using the download feature, make sure to configure Chrome settings:

- Works only on Walmart's order pages
- Download speed may vary based on network conditions
- Large batch downloads may take several minutes to complete
#### 1. Configure Download Settings:
- Open Chrome Settings or paste the following link in the address bar:
```
chrome://settings/downloads
```
- Click on "Downloads" in the left sidebar if not already selected
- Turn OFF "Ask where to save each file before downloading"
- Turn OFF "Show downloads when they're done"

## Troubleshooting
#### 2. Enable Automatic Downloads:
```
chrome://settings/content/siteDetails?site=https%3A%2F%2Fwww.walmart.com#:~:text=Automatic%20downloads
```
- Open a new Chrome tab and paste the above link
- Find "Automatic downloads" option
- Set it to "Allow" (instead of Ask or Block)

If you encounter issues:
#### Alternative Method: (If the above link doesn't work):
```
chrome://settings/content/automaticDownloads
```
- Open a new Chrome tab and paste the above link
- Under "**Allowed to automatically download multiple files**", click Add
- Enter `[*.]walmart.com` and click Add

1. Ensure you're on a valid Walmart orders page
> **Important**: All these settings are required for bulk downloads to work properly. Make sure to add walmart.com under "**Allowed to automatically download multiple files**" and NOT under "Not allowed to automatically download multiple files"
If you still encounter issues:

1. Read FAQs in the extension popup for common problems
2. Check that the extension has necessary permissions
3. Try refreshing the page before downloading
4. For batch downloads, allow sufficient time between orders
4. For batch downloads, try processing fewer orders at once

If you're still facing issues, please submit a detailed bug report.

## Performance Tips

For best results when batch downloading:

1. Close unnecessary browser tabs
2. Start with smaller batches (5-10 orders)
3. Ensure stable and fast internet connection
4. Allow the extension to complete its process without switching tabs or changing windows
5. Keep the popup window open during downloads


## Contributing

Expand Down Expand Up @@ -113,3 +164,8 @@ This extension:
- Doesn't collect any personal data
- Processes all information locally
- Doesn't send data to external servers
- Only blocks images for performance optimization

## Acknowledgments

Special thanks to all the users who provided feedback for making this extension more efficient and user-friendly.
108 changes: 108 additions & 0 deletions content.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,107 @@ let allOrderNumbers = new Set();
let currentPage = 0;
let isProcessing = false;

function removeAllImages() {
// Remove background images from elements
const allElements = document.getElementsByTagName('*');
for (let element of allElements) {
if (element.style) {
element.style.backgroundImage = 'none';
}
}

// Remove all img elements
const images = document.querySelectorAll('img');
images.forEach(img => {
img.remove();
});

// Remove picture elements
const pictures = document.querySelectorAll('picture');
pictures.forEach(pic => {
pic.remove();
});

// Remove CSS background images
const styleSheets = Array.from(document.styleSheets);
styleSheets.forEach(sheet => {
try {
const rules = Array.from(sheet.cssRules || sheet.rules);
rules.forEach((rule, index) => {
if (rule.style && rule.style.backgroundImage) {
rule.style.backgroundImage = 'none';
}
});
} catch (e) {
// Handle cross-origin stylesheet errors silently
}
});
}

function blockImageLoading() {
// Override Image constructor
const originalImage = window.Image;
window.Image = function() {
const dummyImage = {};
Object.defineProperty(dummyImage, 'src', {
set: function() { return ''; },
get: function() { return ''; }
});
return dummyImage;
};

// Block image loading using Content-Security-Policy
const meta = document.createElement('meta');
meta.setAttribute('http-equiv', 'Content-Security-Policy');
meta.setAttribute('content', "img-src 'none'"); // Fixed CSP directive
document.head.appendChild(meta);

// Prevent loading through srcset
HTMLImageElement.prototype.setAttribute = new Proxy(HTMLImageElement.prototype.setAttribute, {
apply(target, thisArg, argumentsList) {
const [attr] = argumentsList;
if (attr === 'src' || attr === 'srcset') {
return;
}
return Reflect.apply(target, thisArg, argumentsList);
}
});

// Intercept image loading
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeName === 'IMG' || node.nodeName === 'PICTURE') {
node.remove();
}
if (node.getElementsByTagName) {
const images = node.getElementsByTagName('img');
const pictures = node.getElementsByTagName('picture');
Array.from(images).forEach(img => img.remove());
Array.from(pictures).forEach(pic => pic.remove());
}
});
});
});

observer.observe(document.documentElement, {
childList: true,
subtree: true
});
}

function aggressiveImageBlocking() {
// Add style to hide images immediately


removeAllImages();
blockImageLoading();

// Additional cleanup passes
setTimeout(removeAllImages, 500);
setTimeout(removeAllImages, 1000);
}

// Function to wait for an element to appear
async function waitForElement(selector, timeout = 30000) {
const startTime = Date.now();
Expand All @@ -21,13 +122,20 @@ async function waitForElement(selector, timeout = 30000) {
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === "collectOrderNumbers") {
// Handle collection asynchronously
aggressiveImageBlocking();
handleCollectOrderNumbers().then(sendResponse);
return true; // Indicates we'll send response asynchronously
} else if (request.action === "clickNextButton") {
// Handle next button click asynchronously
aggressiveImageBlocking();
handleClickNextButton().then(sendResponse);
return true;
} else if (request.action === "blockImagesForDownload") {
aggressiveImageBlocking();
sendResponse({ success: true });
return true;
} else if (request.method === "downloadXLSX") {
aggressiveImageBlocking();
// Array to store all order items
let orderItems = [];

Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Walmart Invoice Exporter",
"version": "2.4",
"version": "2.5",
"description": "Download Walmart order details in xlsx format",
"permissions": ["activeTab"],
"host_permissions": ["https://www.walmart.com/*"],
Expand Down
29 changes: 24 additions & 5 deletions popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,21 +258,40 @@ async function downloadSelectedOrders() {
// Wait for page load and trigger download with timeout
await Promise.race([
new Promise((resolve, reject) => {
function listener(tabId, info) {
async function handleDownload(tabId, info) {
if (tabId === downloadTab.id && info.status === "complete") {
chrome.tabs.onUpdated.removeListener(listener);
setTimeout(() => {
chrome.tabs.onUpdated.removeListener(handleDownload);

try {
// First, block images
await new Promise((blockResolve) => {
chrome.tabs.sendMessage(downloadTab.id, { action: "blockImagesForDownload" }, (response) => {
if (chrome.runtime.lastError) {
console.error("Error blocking images:", chrome.runtime.lastError);
}
// Continue even if blocking fails
blockResolve();
});
});

// Wait a bit longer for the page to stabilize
await new Promise((r) => setTimeout(r, 2000));

// Then proceed with download
chrome.tabs.sendMessage(downloadTab.id, { method: "downloadXLSX" }, (response) => {
if (chrome.runtime.lastError) {
reject(new Error(`Failed to download order #${orderNumber}: ${chrome.runtime.lastError.message}`));
} else {
resolve();
}
});
}, 2000);
} catch (error) {
reject(error);
}
}
}
chrome.tabs.onUpdated.addListener(listener);

chrome.tabs.onUpdated.addListener(handleDownload);
}),
new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout downloading order #${orderNumber}`)), 30000))
]);
Expand Down
Binary file removed screenshot.png
Binary file not shown.
Binary file added screenshot.webp
Binary file not shown.

0 comments on commit 1139df1

Please sign in to comment.