Using a WebExtension, I am trying to programmatically generate an HTML file like this:
<html><head><meta><title>example</title></head><body><p>Hello, world!</p></body></html>
and then download it using this method. (Background: I am generating a client-side redirect.)
Here's my manifest.json:
{
"name": "Download HTML",
"description": "Generates an HTML file and downloads it",
"manifest_version": 2,
"version": "0.1",
"permissions": [
"activeTab"
],
"browser_action": {
"default_title": "Download HTML"
},
"background": {
"scripts": ["background.js"]
}
}
and here's my background.js:
function downloadHTML(tab) {
console.log('Begin downloadHTML()')
function generateHTML(title) {
var newHTML = document.createElement('html');
var newHead = document.createElement('head');
var newTitle = document.createElement('title');
newTitle.text = title;
var newMeta = document.createElement('meta');
var newBody = document.createElement('body');
var newPar = document.createElement('p');
var newText = document.createTextNode('Hello, world!');
newPar.appendChild(newText);
newBody.appendChild(newPar);
newHead.appendChild(newMeta);
newHead.appendChild(newTitle);
newHTML.append(newHead);
newHTML.append(newBody);
return newHTML;
}
// Now make an anchor to click to download the HTML.
var tempAnchor = document.createElement('a');
var myHTML = generateHTML(tab.title);
var HTMLBlob = new Blob([myHTML.outerHTML], {type: 'text/html'});
tempAnchor.href = URL.createObjectURL(HTMLBlob);
var filename = 'index.html';
tempAnchor.download = filename
tempAnchor.style.display = 'none';
document.body.appendChild(tempAnchor);
tempAnchor.click();
document.body.removeChild(tempAnchor);
console.log('End downloadHTML()')
}
// Add downloadHTML() as a listener to clicks on the browser action.
browser.browserAction.onClicked.addListener(downloadHTML);
I've run the extension on this page:
http://info.cern.ch/hypertext/WWW/TheProject.html
When I do so, the browser console confirms that the function runs from start to finish.
Begin downloadHTML() background.js:2:3
End downloadHTML() background.js:31:3
However, there is no download prompt, and I receive this error message:
TypeError: this.mDialog is null [Learn More] nsHelperAppDlg.js:173:5
The "Learn More" just links to "TypeError":
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_type
When I debug the extension, I find these messages instead.
Webconsole context has changed
TypeError: can't access dead object [Learn More] accessible.js:140:5
The "Learn More" links to information about dead objects.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Dead_object
I'm guessing that the HTML elements are not persisting between calls to document.creatElement(). I've tried moving the body of generateHTML() out into its parent function, but that did not help.
How can I make sure the HTML persists? I don't want to modify the actual tab HTML, I just want to access the tab's title (and eventually URL). I looked at the Web Storage API, but I want to store HTML, not key-value pairs.
I am running Firefox version 63.0.3.