| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 | const JSZip = require('jszip');window.ExportHtml = Popup => {  const saveAs = function(blob, filename) {    const dl = document.createElement('a');    dl.href = window.URL.createObjectURL(blob);    dl.onclick = event => document.body.removeChild(event.target);    dl.style.display = 'none';    dl.target = '_blank';    dl.download = filename;    document.body.appendChild(dl);    dl.click();  };  const asyncForEach = async function(array, callback) {    for (let index = 0; index < array.length; index++) {      await callback(array[index], index, array);    }  };  const getPageHtmlString = () => {    return `<!doctype html>${window.document.querySelector('html').outerHTML}`;  };  const removeAnchors = htmlString => {    const replaceOpenAnchor = htmlString.replace(      new RegExp('<a ', 'gim'),      '<span ',    );    return replaceOpenAnchor.replace(new RegExp('</a', 'gim'), '</span');  };  const ensureSidebarRemoved = () => {    document.querySelector('.board-sidebar.sidebar').remove();  };  const addJsonExportToZip = async (zip, boardSlug) => {    const downloadJSONLink = document.querySelector('.download-json-link');    const downloadJSONURL = downloadJSONLink.href;    const response = await fetch(downloadJSONURL);    const responseBody = await response.text();    zip.file(`data/${boardSlug}.json`, responseBody);  };  const closeSidebar = () => {    document.querySelector('.board-header-btn.js-toggle-sidebar').click();  };  const cleanBoardHtml = () => {    Array.from(document.querySelectorAll('script')).forEach(elem =>      elem.remove(),    );    Array.from(      document.querySelectorAll('link:not([rel="stylesheet"])'),    ).forEach(elem => elem.remove());    document.querySelector('#header-quick-access').remove();    Array.from(      document.querySelectorAll('#header-main-bar .board-header-btns'),    ).forEach(elem => elem.remove());    Array.from(document.querySelectorAll('.list-composer')).forEach(elem =>      elem.remove(),    );    Array.from(      document.querySelectorAll(        '.list-composer,.js-card-composer, .js-add-card',      ),    ).forEach(elem => elem.remove());    Array.from(document.querySelectorAll('[href]:not(link)')).forEach(elem =>      elem.attributes.removeNamedItem('href'),    );    Array.from(document.querySelectorAll('[href]')).forEach(elem => {      // eslint-disable-next-line no-self-assign      elem.href = elem.href;      // eslint-disable-next-line no-self-assign      elem.src = elem.src;    });    Array.from(document.querySelectorAll('.is-editable')).forEach(elem => {      elem.classList.remove('is-editable');    });  };  const getBoardSlug = () => {    return window.location.href.split('/').pop();  };  const getStylesheetList = () => {    return Array.from(      document.querySelectorAll('link[href][rel="stylesheet"]'),    );  };  const downloadStylesheets = async (stylesheets, zip) => {    await asyncForEach(stylesheets, async elem => {      const response = await fetch(elem.href);      const responseBody = await response.text();      const finalResponse = responseBody.replace(        new RegExp('packages/[^/]+/upstream/', 'gim'),        '../',      );      const filename = elem.href        .split('/')        .pop()        .split('?')        .shift();      const fileFullPath = `style/${filename}`;      zip.file(fileFullPath, finalResponse);      elem.href = `../${fileFullPath}`;    });  };  const getSrcAttached = () => {    return Array.from(document.querySelectorAll('[src]'));  };  const downloadSrcAttached = async (elements, zip, boardSlug) => {    await asyncForEach(elements, async elem => {      const response = await fetch(elem.src);      const responseBody = await response.blob();      const filename = elem.src        .split('/')        .pop()        .split('?')        .shift();      const fileFullPath = `${boardSlug}/${elem.tagName.toLowerCase()}/${filename}`;      zip.file(fileFullPath, responseBody);      elem.src = `./${elem.tagName.toLowerCase()}/${filename}`;    });  };  const removeCssUrlSurround = url => {    const working = url || '';    return working      .split('url(')      .join('')      .split('")')      .join('')      .split('"')      .join('')      .split("')")      .join('')      .split("'")      .join('')      .split(')')      .join('');  };  const getCardCovers = () => {    return Array.from(document.querySelectorAll('.minicard-cover')).filter(      elem => elem.style['background-image'],    );  };  const downloadCardCovers = async (elements, zip, boardSlug) => {    await asyncForEach(elements, async elem => {      const response = await fetch(        removeCssUrlSurround(elem.style['background-image']),      );      const responseBody = await response.blob();      const filename = removeCssUrlSurround(elem.style['background-image'])        .split('/')        .pop()        .split('?')        .shift()        .split('#')        .shift();      const fileFullPath = `${boardSlug}/covers/${filename}`;      zip.file(fileFullPath, responseBody);      elem.style = "background-image: url('" + `covers/${filename}` + "')";    });  };  const addBoardHTMLToZip = (boardSlug, zip) => {    ensureSidebarRemoved();    const htmlOutputPath = `${boardSlug}/index.html`;    zip.file(      htmlOutputPath,      new Blob([removeAnchors(getPageHtmlString())], {        type: 'application/html',      }),    );  };  return async () => {    const zip = new JSZip();    const boardSlug = getBoardSlug();    await addJsonExportToZip(zip, boardSlug);    Popup.close();    closeSidebar();    cleanBoardHtml();    await downloadStylesheets(getStylesheetList(), zip);    await downloadSrcAttached(getSrcAttached(), zip, boardSlug);    await downloadCardCovers(getCardCovers(), zip, boardSlug);    addBoardHTMLToZip(boardSlug, zip);    const content = await zip.generateAsync({ type: 'blob' });    saveAs(content, `${boardSlug}.zip`);    window.location.reload();  };};
 |