How I Built a Chrome Extension to Download All Documents for My Wife

How I Built a Chrome Extension to Download All Documents for My Wife

A fun and practical journey into Chrome extension development

The other day, my wife asked me to help her download some documents from a platform she uses for work. There were dozens of them, and to our surprise, the platform didn't have a "download all" feature! Instead of spending hours manually downloading each document, I figured it was the perfect opportunity to flex my developer muscles and create a Chrome extension to make our lives easier. So, grab a cup of coffee, and let's dive into this exciting adventure together!

The Birth of an Idea

Like any good spouse, I wanted to save my wife from the drudgery of clicking each link one by one. But how could I do it? That's when it hit me: a Chrome extension that would automatically download all documents with a single click! I knew I had the skills, and it was time to put them to good use.

Laying the Foundation

To kick things off, I needed to understand the basic structure of a Chrome extension. After a quick search, I found out that the three main components are:

  1. manifest.json: The configuration file that contains metadata about the extension, like its name, description, version, and permissions.
  2. popup.html and popup.js: The HTML and JavaScript files that make up the extension's user interface.
  3. content.js: The JavaScript file that interacts with the webpage content and performs the core functionality of the extension.

With this knowledge in hand, I was ready to start building the extension to end all extensions (well, at least for downloading documents).

Crafting the User Interface

For the user interface, I whipped up a simple but elegant popup with input fields for the link selector and timeout duration between downloads. I also added a button to start the download process and a label to display feedback during the operation.

<!-- A snippet of popup.html -->
<label for="linkSelector">All Documents Selector:</label>
<input type="text" id="linkSelector" placeholder=".your-link-selector" />

<label for="timeout">Timeout (ms):</label>
<input type="number" id="timeout" placeholder="5000" />

<button id="downloadBtn">Download All Documents</button>
<p id="feedback">Download completed!</p>

Making It Work

The real magic happens in the content.js file, where I implemented a function called downloadDocuments to iterate through the table of links, click each one to trigger the download, and wait for the specified timeout between clicks.

// A snippet of content.js
function downloadDocuments(linkSelector, timeout) {
  const links = Array.from(document.querySelectorAll(linkSelector));
  let currentIndex = 0;

  function downloadNext() {
    if (currentIndex < links.length) {
      links[currentIndex].click();
      currentIndex++;
      setTimeout(downloadNext, timeout);
    }
  }
  downloadNext();
}

Connecting the Dots

To bring it all together, I set up a message listener in content.js to listen for messages from the popup. When the "Download All Documents" button is clicked, the popup.js file sends a message containing the link selector and timeout, which content.js uses to initiate the download process.

// A snippet of popup.js
document.getElementById('downloadBtn').addEventListener('click', () => {
  const linkSelector = document.getElementById('linkSelector').value;
  const timeout = document.getElementById('timeout').value;

  chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
    chrome.tabs.sendMessage(tabs[0].id, {
        action: 'downloadDocuments',
  linkSelector,
  timeout,
});

// A snippet of content.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === 'downloadDocuments') {
downloadDocuments(request.linkSelector, request.timeout);
}
});

Adding Some Polish

I wanted to make the extension even more user-friendly, so I decided to display the index of the clicked link in the popup during the download process. To achieve this, I set up a message listener in `popup.js` to listen for messages from `content.js`. When a link is clicked, `content.js` sends a message containing the index, which `popup.js` uses to update the feedback label.


// A snippet of content.js
function downloadNext() {
  if (currentIndex < links.length) {
    links[currentIndex].click();
    // Send the current index to the popup
    chrome.runtime.sendMessage({ action: 'linkClicked', index: currentIndex });
    currentIndex++;
    setTimeout(downloadNext, timeout);
  }
}

// A snippet of popup.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'linkClicked') {
    const feedback = document.getElementById('feedback');
    feedback.style.display = 'block';
    feedback.textContent = `${request.index + 1}. element is clicked`;
  }
});
T

The Moment of Truth

With everything in place, it was time to test the extension. I added it to Chrome, opened my wife's work platform, and clicked the "Download All Documents" button. Lo and behold, it worked like a charm! The documents started downloading one by one, and my wife's face lit up with joy.

Wrapping Up

In the end, building the Chrome extension was a fun and rewarding experience. Not only did I get to learn more about Chrome extension development, but I also saved my wife countless hours of tedious work. If you ever find yourself in a similar situation, I hope this little adventure of mine can serve as inspiration to create your own helpful and enjoyable Chrome extensions!

And hey, if you're interested in trying out the extension I built, you can find it on the Chrome Web Store. Just remember to disable the "Ask where to save each file before downloading" property in your Chrome settings at chrome://settings/?search=Downloads for a seamless experience. Enjoy!


Note: You can find all the code and usage instructions for the Bulk Document Downloader extension on my GitHub repository. Visit https://github.com/ercan2158/bulk-document-downloader-extension to access the full source code and get started with the extension.