How to render HTML pages as PNG/JPEG images with URL array using Javascript only?

92
January 14, 2021, at 5:10 PM

I am building a chrome extension using Javascript which gets URLs of the opened tabs and saves the html file, but the problem with html is that it does not render images on webpages fully. So i changed my code to loop each URLs of the tabs and then save each html pages as image file automatically in one click on the download icon of the chrome extension. I have been researching for more than 2 days but nothing happened. Please see my code files and guide me. I know there is library in nodejs but i want to perform html to jpeg/png maker using chrome extension only.

Only icons i have not attached which i have used in this extension, all code i have and the text in popup.js which is commented i have tried.

Current output of the attached code

File popup.js - This file has functions which gets all the URLs of the opened tabs in the browser window

function stylePop() {
    inStyle = document.createElement('style');
    inStyle.type = 'text/css';
    inStyle.id = 'instyle';
    if (navigator.appVersion.indexOf("Win")>-1) {
        inStyle.innerHTML += " /* Font */ @font-face{ font-family: 'SEGOEUIL'; src: local('☺'), url('https://raw.githubusercontent.com/lmmx/websiteresources/master/fonts/SEGOEUIL.svg') format(\"svg\"), url('https://raw.githubusercontent.com/lmmx/websiteresources/master/fonts/SEGOEUIL.woff') format('woff'), url('https://raw.githubusercontent.com/lmmx/websiteresources/master/fonts/SEGOEUIL.ttf') format('truetype');}";
}
    else inStyle.innerHTML += ' /* Font */ @font-face {font-family: "SEGOEUIL";src: url(\'https://raw.githubusercontent.com/lmmx/websiteresources/master/fonts/SEGOEUIL.eot\');src: local("Segoe UI Light"), url(\'https://raw.githubusercontent.com/lmmx/websiteresources/master/fonts/SEGOEUIL.woff\') format("woff"), url(\'https://raw.githubusercontent.com/lmmx/websiteresources/master/fonts/SEGOEUIL.ttf\') format("truetype");}'
    document.body.appendChild(inStyle);
}
function isURL(str) { // URL checking RegEx courtesy of Matthew O'Riordan http://blog.mattheworiordan.com/post/13174566389/url-regular-expression-for-links-with-or-without-the
    var pattern = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/g
    if(!pattern.test(str)) {
        return false;
    } else {
        return true;
    }
}
// the old one is recursive (adds items already added!)
function pasteIn(e) {
    txt = document.querySelector('#txtin');
    setTimeout(function(){
        temparray = []; tabUrls = [];
        temparray.push(txt.value.replace(/,\s|\r|\f/g,'\n').replace(/\n{2,}/g,'\n').split('\n'));
        for (k=0;k<temparray[0].length;k++) {
            tabUrls.push(temparray[0][k]);
        }
        URLn = tabUrls[tabUrls.length-1];
        if (!isURL(URLn)) {
            (URLn == '' || URLn == ' ' || URLn == '\t') ? txt.value = null :    txt.value = URLn;
            tabUrls.pop([tabUrls.length]);
    }
    else txt.value = null;
    urlHolder = document.createElement('div');
    document.body.appendChild(urlHolder);
    for (i=0;i<tabUrls.length;i++) {
        urlbox = document.createElement('input');
        urlbox.type = 'url';
        urlbox.value = tabUrls[i];
        document.querySelector('#main').insertBefore(urlbox,document.querySelector('textarea'));
    }
    }, 0);
}
function enterUp(e) {
    if (e.keyCode === 13) {
        pasteIn();
    }
}
closeSVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 785.714 1000" preserveAspectRatio="xMinYMin meet" width="100%" height="100%"><path d="M724.284 737.74q0 22.32 -15.624 37.944l-75.888 75.888q-15.624 15.624 -37.944 15.624t-37.944 -15.624l-164.052 -164.052 -164.052 164.052q-15.624 15.624 -37.944 15.624t-37.944 -15.624l-75.888 -75.888q-15.624 -15.624 -15.624 -37.944t15.624 -37.944l164.052 -164.052 -164.052 -164.052q-15.624 -15.624 -15.624 -37.944t15.624 -37.944l75.888 -75.888q15.624 -15.624 37.944 -15.624t37.944 15.624l164.052 164.052 164.052 -164.052q15.624 -15.624 37.944 -15.624t37.944 15.624l75.888 75.888q15.624 15.624 15.624 37.944t-15.624 37.944l-164.052 164.052 164.052 164.052q15.624 15.624 15.624 37.944z"></path></svg>'
function urlGet(){
    tabUrls = [];
    chrome.tabs.query({currentWindow: true}, function(tabs){
    var div = document.createElement('div');
    for (i=0;i<tabs.length;i++) {
        tabUrls.push(tabs[i].url);
    } 
    header = document.createElement('h1');
    header.innerHTML = 'Tabs to download';
    list = document.createElement('div');
    list.id = 'tablist';
    list.innerHTML = tabUrls.join('</p><a class="close">'+closeSVG+'</a></div><br /><div id="p"><p>').replace(/^/,'<div id="p"><p>').replace(/$/,'</p><a class="close">'+closeSVG+'</a></div>');
    boxes = list.querySelectorAll('#p');
    for (i=0;i<boxes.length;i++) {
        boxes[i].setAttribute('data-origin', tabUrls[i]);
    }
    div.innerHTML = header.outerHTML + list.outerHTML;
    div.id = 'main';
    document.body.appendChild(div);
    formsect = document.createElement('section');
    editbtn = document.createElement('button');
    editSVG = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="20px" height="20px" viewBox="0 0 600 600" enable-background="new 0 0 600 600" xml:space="preserve" xmlns:xml="http://www.w3.org/XML/1998/namespace"><g xmlns="http://www.w3.org/2000/svg" transform="translate(700, 0) scale(-1, 1)"><path fill="#404040" d="M222.29,43.907c8.002,0,16.004,0,24.008,0c17.984,5.355,34.246,12.437,46.018,24.009 c-37.514,40.516-78.527,77.527-116.042,118.04c-14.398-9.606-19.908-28.114-26.006-46.017c0-8.005,0-16.008,0-24.011 C158.911,76.563,182.918,52.555,222.29,43.907z"></path><path fill="#404040" d="M322.325,101.928c66.083,59.522,129.868,127.868,196.07,194.071c20.882,20.882,50.497,41.409,64.025,64.023 c17.16,28.683,26.672,65.598,40.013,98.032c13.145,31.96,26.889,64.208,40.017,98.039c-33.778-13.111-66.171-26.906-98.034-40.019 c-32.584-13.395-69.32-22.832-98.037-40.013c-22.408-13.406-45.211-43.211-66.023-64.021 c-63.788-63.786-128.009-130.914-192.067-192.069C243.131,177.457,285.814,142.774,322.325,101.928z M524.398,418.042 c-26.342-11.761-47.98,8.89-48.018,36.017c38.498,14.85,74.458,32.241,114.037,46.012c5.916-5.428,13.42-9.254,16.01-18.006 c-14.952-37.733-30.96-74.41-46.02-112.039C533.29,370.06,512.638,391.702,524.398,418.042z"></path></g></svg>';
    editbtn.innerHTML = editSVG;
    editbtn.id = 'editbtn';
    
    btn = document.createElement('button');
    dlSVG = '<svg id="dlsvg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1082.5 1000" preserveAspectRatio="xMinYMin meet" width="100%" height="100%"><path d="m1.5 597.7q0 104.4 72.7 179.2t177.3 79.5q9.2 0 9.2-8.7v-69.9q0-9.2-9.2-9.2q-66.9-3.5-114-53.3t-47.2-117.6q0-65 44.5-113.1t109.8-55.9l27.4-1.5q9.7 0 9.7-8.7l3.9-28.9q7.9-84.4 71.3-141.3t149.4-56.9q85 0 148.7 56.9t72.5 141.3l3.9 30.3q0 8.8 9.3 8.8h84q69.3 0 120.4 50.3t51 118.7q0 67.8-47.1 117.6t-114 53.3q-10.3 0-10.3 9.2v69.9q0 8.7 10.3 8.7q104-3.4 176.2-78.6t72.3-180.1q0-70.4-34.7-129.4t-94.2-93.1t-129.9-33.9h-16.6q-25.4-104.5-109.6-171.4t-192.2-66.9q-110.3 0-196 68.4t-110.1 175.3q-85.9 20-142.3 90.6t-56.4 160.4z m362.8 79.5q0 18.1 13.1 31.3l134.3 135.7q9.8 12.2 30.3 12.2q22 0 31.7-12.2l134.8-135.7q13.2-14.2 13.2-31.3q0-18-13-30.2t-31.5-12.2t-32.2 12.2l-58.6 57.6v-207.5q0-18.6-12.9-30.8t-31.5-12.2t-30.8 12.2t-12.2 30.8v207.5l-57.6-57.6q-13.7-12.2-32.2-12.2q-19.6 0-32.2 11.9t-12.7 30.5z"></path></svg>'
    btn.innerHTML = dlSVG;
    btn.setAttribute('id','btnDL');
    // formsect.innerHTML = editbtn.outerHTML + DOIbtn.outerHTML + btn.outerHTML;
    formsect.innerHTML = editbtn.outerHTML + btn.outerHTML;
    document.body.appendChild(formsect);
    
    document.querySelector('#btnDL').addEventListener('click', function(e) {
        tabDL();
    })
    document.querySelector('#editbtn').addEventListener('click', function(e) {
    textarea = document.createElement('textarea');
    textarea.id = 'txtin'
    edHead = document.createElement('h1');
    edHead.innerHTML = 'Enter your download links';
    div.childNodes[0].outerHTML = edHead.outerHTML;
    div.childNodes[1].outerHTML = textarea.outerHTML;
    document.querySelector('textarea').addEventListener('paste', pasteIn);
    document.querySelector('textarea').addEventListener('keyup', enterUp);
    this.remove();
    tabUrls = [];
    document.querySelector('textarea').focus();
    });
    document.querySelector('#btnDL').focus();
    closers = document.querySelectorAll('#p');
    for (c=0;c<closers.length;c++) {
        closers[c].querySelector('.close').addEventListener('click',function(e) {
            if (document.querySelectorAll('#p').length > 1) {
                dataOrigin = this.parentNode.getAttribute('data-origin');
                urlIndex = tabUrls.indexOf(dataOrigin);
                if (urlIndex > -1) { tabUrls.splice(urlIndex, 1) }
                else console.log("original URL not found in array - this shouldn't happen");
                this.parentNode.nextSibling.remove();
                this.parentNode.remove();
            }
            else {
                this.parentNode.querySelector('p').innerText = '';
                this.parentNode.removeAttribute('data-origin');
                tabUrls = [];
            }
        })
        closers[c].querySelector('p').addEventListener('mouseover',function(e) {
            this.setAttribute('contenteditable','true');
        })
    }
});
}
function httpGet(theUrl)
{
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            return xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET", theUrl, false );
    xmlhttp.send();    
}
function tabDL(){
    
    for (i=0;i<tabUrls.length;i++) {
    
            console.log(tabUrls[i])
            console.log("----------")
            // chrome.downloads.download({url: tabUrls[i]});
            Webpage_HTML = httpGet(tabUrls[i])
            console.log("---------------------------------")
            console.log(Webpage_HTML)
            console.log("---------------------------------")
            // location.href = tabUrls[i]
            // exports(window.location.href)
            
            // function makeHttpObject() {
            //  try {return new XMLHttpRequest();}
            //  catch (error) {}
            //  try {return new ActiveXObject("Msxml2.XMLHTTP");}
            //  catch (error) {}
            //  try {return new ActiveXObject("Microsoft.XMLHTTP");}
            //  catch (error) {}
              
            //  throw new Error("Could not create HTTP request object.");
            // }
              
            // var request = makeHttpObject();
            // request.open("GET", tabUrls[i], true);
            // request.send(null);
            // request.onreadystatechange = function() {
            //  if (request.readyState == 4){
            //      console.document(request.responseText)
            //  }
            // };
    }
}
document.addEventListener('DOMContentLoaded', function () {
    stylePop();
    urlGet();
});

File popup.html - This file represent icon and click functionality on the chrome browser search bar

<!doctype html>
<html>
  <head>
    <style>
    body {
        min-width: 357px;
        overflow-x: hidden;
    }
    * {
        font-family: "SEGOEUIL", Helvetica, Tahoma, sans-serif;
    }
    #main {
        width: 600px;
        font-size: smaller;
        margin: 1.5em 1.5em 0.5em 1.5em;
        cursor: default;
        line-height: 0;
        border: 6px solid rgba(0, 0, 0, 0.37);
        border-radius: 0 36px;
        padding: 1.5em;
    }
    #main::selection, #main *::selection {
        background-color: transparent;
    }
    #main h1 {
        font-weight: normal;
        line-height: 1 !important;
        font-size: 50px;
        margin: 0 0 0.4em 0;
    }
    #main > * {
        margin-left: 20px !important;
    }
    input[type="url"] {
        border: none;
        outline: none;
        width: 80%;
    }
    #tablist {
        overflow-y: scroll !important;
        max-height: 400px;
    }
    #tablist p {
        width: 97%;
        height: 1.6rem;
        cursor: auto;
        overflow-y: overlay;
        white-space: nowrap;
        margin: 0;
        padding-bottom: 2px;
    }
    #tablist p:active, #tablist p:focus {
        text-overflow: initial;
        outline: none;
    }
    #p p::selection {
        background: #62C9BC;
    }
    div#p {
        overflow: auto!important;
        width: 100%;
        line-height: 2 !important;
    }
    a.close {
        -webkit-box-shadow: inset 0 0 5px 0 rgba(255,255,255,0.5);
        line-height: 1.1 !important;
        font-size: 15px;
        display: block;
        height: 18px;
        -webkit-border-radius: 32px;
        float: right;
        padding: 0 4px;
        margin-top: -24px;
        -webkit-transition: all 0.4s ease-out;
        transition: all 0.4s ease-out;
    }
    .close svg {
        width: 10px;
        height: 10px;
        fill: #CFCFCF;
        -webkit-transition: all 0.4s ease-out;
        transition: all 0.4s ease-out;
    }
    #p p:active + .close, #p p:focus + .close {
        opacity: 0;
    }
    #p p:hover + .close svg, .close:hover svg {
        fill: #51C0CF;
    }
/*Scrollbars*/
    p::-webkit-scrollbar {
        display: none;
    }
    #textin::-webkit-scrollbar, #tablist::-webkit-scrollbar {
        width: 18px;
    }
    #textin::-webkit-scrollbar-track, #tablist::-webkit-scrollbar-track {
        background-color: transparent;
    }
    #textin::-webkit-scrollbar-thumb, #tablist::-webkit-scrollbar-thumb {
        border: 4px solid rgba(0, 0, 0, 0);
        -webkit-border-radius: 16px;
        background-clip: padding-box;
        -webkit-box-shadow: inset 0 0 0px rgba(0,0,0,.3);
        background-color: #dadada;
    }
    #txtin::-webkit-scrollbar-corner, #tablist::-webkit-scrollbar-corner {
        background-color: transparent;
    }
/* Buttons */
    section {
        margin: 0 1.5em;
        height: 24px;
        border: 3px solid transparent;
    }
    section > svg {
        float: left;
    }
    #editbtn {
        margin-right: 60px;
    }
    #editbtn svg * {
        fill: #000000;
    }
    #editbtn {
        background: none;
        border: 0;
        outline: none;
        height: 27px;
    }
    
    section button {
        cursor: pointer;
    }
    #btnDL {
        float: right;
        background: white;
        margin-top: -4px;
        margin-bottom: 5px;
        border: 0;
        border-radius: 430px;
        color: white;
        padding: 1px 3px;
        font-size: 1em;
        outline: none;
        box-shadow: inset 2px 2px 6px 0 rgba(255,255,255,0.5);
        -webkit-box-shadow: inset 2px 2px 6px 0 rgba(255,255,255,0.5);
        -webkit-transition: all 0.4s ease-out;
    }
    #btnDL:active, #btnDL:visited {
        margin-top: -3px;
        margin-bottom: 4px;
        box-shadow: inset 0 -1px 1px 0 #7E7E7E, 0 2px 13px 0 #fff;
        -webkit-box-shadow: inset 0 -1px 1px 0 #7E7E7E, 0 2px 13px 0 #fff;
        text-shadow: none;
    }
    #dlsvg {
        width: 37px;
        height: 36px;
    }
    #dlsvg * {
        fill: #000000;
        width: 20px;
        height: 26px;
    }
/* Editing */
    #txtin {
        outline: none;
        border-radius: 16px;
        width: 90%;
        padding: 8px;
        border: 0;
        border-style: groove;
        background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(251, 247, 255, 0.63)), color-stop(100%,rgba(229, 241, 255, 0.51)));
        height: 146px;
        margin: 0px;
        -webkit-transition: all 0.4s ease-out;
        transition: all 0.6s ease-out 0.4s;
    }
    input[type="url"] + #txtin {
        height: 80px;
    }
    </style>
    <!--
      - JavaScript and HTML must be in separate files: see our Content Security
      - Policy documentation[1] for details and explanation.
      -
      - [1]: http://developer.chrome.com/extensions/contentSecurityPolicy.html
     -->
    <script src="popup.js"></script>
  </head>
  <body>
</body>
</html>

File manifest.json - This file is used by the chrome browser to execute the chrome extension

{
  "update_url": "https://clients2.google.com/service/update2/crx",
  
    "manifest_version": 2,
  
    "name": "Exhibits maker",
    "description": "One-click download for files from open tabs and lists of URLs",
  
    "version": "1.4.0.2",
    "icons": {
      "16": "icon16.png",
    "48": "icon48.png",
    "128": "icon128.png"
    },
    "browser_action": {
      "default_icon": "icon.png",
      "default_popup": "popup.html"
    },
    "permissions": [
      "downloads", "tabs", "<all_urls>"
    ],
    "content_security_policy": "script-src 'self' https://www.googleapis.com; object-src 'self'",
    "options_page": "options.html"
  }
READ ALSO
Get count of items that matches a condition from mongo db in node js

Get count of items that matches a condition from mongo db in node js

I am new to mongo dbI have a scenario where I need to check into collection and the count of items having gameDate = current date

107
&ldquo;Duplicate entry&rdquo; even though the column has UNIQUE constraint

“Duplicate entry” even though the column has UNIQUE constraint

I'm trying to drop some columns which I'm no longer using in my tableI've got a single column with a UNIQUE constraint

80
Run multiple processes in single celery worker on a machine with single CPU

Run multiple processes in single celery worker on a machine with single CPU

I am researching on Celery as background worker for my flask applicationThe application is hosted on a shared linux server (I am not very sure what this means) on Linode platform

63