генерация HTML в WebExtension приводит к тому, что this.mDialog имеет значение null и не может получить доступ к мертвому объекту - PullRequest
0 голосов
/ 26 ноября 2018

Используя WebExtension , я пытаюсь программно сгенерировать HTML-файл, подобный этому:

<html><head><meta><title>example</title></head><body><p>Hello, world!</p></body></html>

, а затем загрузить его, используя этот метод .(Справочная информация: Я генерирую a клиентское перенаправление .)

Вот мой 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"]
  }
}

и вот мой 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);

Я запустил расширение на этой странице:

http://info.cern.ch/hypertext/WWW/TheProject.html

При этом консоль браузера подтверждает, что функция работаетот начала до конца.

Begin downloadHTML() background.js:2:3
End downloadHTML() background.js:31:3

Однако нет запроса на загрузку, и я получаю это сообщение об ошибке:

TypeError: this.mDialog is null [Learn More] nsHelperAppDlg.js:173:5 

«Подробнее» просто ссылается на «TypeError»:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_type

Когда я отлаживаю расширение, я нахожу эти сообщения вместо этого.

Webconsole context has changed

TypeError: can't access dead object [Learn More] accessible.js:140:5 

«Подробнее» ссылается на информацию о мертвых объектах.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Dead_object

Я предполагаю, что элементы HTML не сохраняются между вызовами document.creatElement().Я попытался переместить тело generateHTML() в родительскую функцию, но это не помогло.

Как я могу убедиться, что HTML сохраняется?Я не хочу изменять фактическую вкладку HTML, я просто хочу получить доступ к заголовку вкладки (и в конечном итоге к URL).Я посмотрел на API веб-хранилища, но хочу хранить HTML, а не пары ключ-значение.

Я использую Firefox версии 63.0.3.

1 Ответ

0 голосов
/ 26 ноября 2018

Вам нужен фактический DOM, чтобы щелкнуть по нему.

В любом случае ... это может быть намного проще

browser.browserAction.onClicked.addListener(downloadHTML);

function downloadHTML() {

  // download to file, downloads string (not DOM)
  const data = '<html><head><meta><title>example</title></head><body><p>Hello, world!</p></body></html>';
  const blob = new Blob([data], {type : 'text/plain;charset=utf-8'});
  const filename = 'something.html';

  // both are fine: chrome.downloads.download or browser.downloads.download
  // requires "downloads" permission
  browser.downloads.download({
    url: URL.createObjectURL(blob),
    filename,
    saveAs: true,  // pops up a Save As dialog, omitting it will save the file to the Downloads folder set in Firefox Options
    conflictAction: 'uniquify' // renames file if filename already exists
  });  
}

Если вы хотите показать фактическую страницу на browserAction тогда было бы проще установить "default_popup" в manifest.json

...