Greasy Fork is available in English.

Συζητήσεις » Αιτήματα Δημιουργίας

programmatically modify pdf or print preview using greasemonkey

§
Δημοσιεύτηκε: 14/09/2015
Επεξεργάστηκε: 14/09/2015

programmatically modify pdf or print preview using greasemonkey

I have an admin page that lists my orders.
I use the shipping companies website to print the labels,
I use greasemonkey to get the order item lists using GM_getValue, and I then append the order lists onto the labels using GM_setValue.
(I can then see what to pack in the box, and cut off the items list before attaching the label to the box.)

Some of the labels are created using html. Some are generated as pdfs.

Is there a way to modify a pdf that is open in firefox using greasemonkey? (or modify print preview).

If greasemonkey were to implement this feature, I would only need a search and replace function. I could then programmatically search for the invoice number on the label and replace it with the invoice # + the order list.

Thanks for reading,

§
Δημοσιεύτηκε: 14/09/2015
Is there a way to modify a pdf that is open in firefox using greasemonkey? (or modify print preview).

I think it would be difficult to modify a PDF. Firefox's built-in PDF viewer shows a generated canvas layer behind a transparent text layer. I think you could change the transparent text layer, but I don't know how you would change the canvas; it seems to behave like an image.

I don't think Greasemonkey can do anything with Firefox's Print Preview screen. There is the Print Edit extension: https://addons.mozilla.org/firefox/addon/print-edit/

§
Δημοσιεύτηκε: 20/09/2015
Επεξεργάστηκε: 26/09/2015

Thanks for your reply. I see the textLayer now.

Right clicking and Inspect Element on the pdf shows an html dom tree like this.

<div id="viewer" class="pdfViewer" ...>
    <div id="pageContainer1" ...>
        <div class="canvasWrapper" ...>
            <canvas id="page1" ...> (mouseover this element and shows a thumbnail of the pdf)
        <div class="textLayer" ...>
            (elements that are an html representation of the pdf, including text inside the pdf).

Here's my testing script

if(window.location.href.indexOf(".pdf") > -1)
{
    //alert("PDF");
    //alert(document.body.innerHTML);

    BorderChildNodes(document.body); //Put a border around everything we can, just to temporarily highlight things.

    var oElm = document.getElementById("viewer");

    trace("oElm.innerHTML #1:"+oElm.innerHTML); //Shows Empty. (Right Click -> Inspect Element shows child elements do exist).

    var oElm = document.createElement("div");

    oElm.innerHTML = "Hello";
    oElm.style.position = "absolute";
    oElm.style.top = "100px";
    oElm.style.left = "200px";
    oElm.style.backgroundColor = "white";
    oElm.style.border = "1px solid black";
    oElm.style.fontSize = "30pt";
    oElm.style.zIndex = "1000"

    //var oDiv = document.getElementById("mainContainer"); //This adds text to the page. But doesn't show in print preview.
    //oDiv.appendChild(oElm);

    document.body.appendChild(oElm); //This adds text to the page. Does show in print preview.

    window.addEventListener('load', function() {
        var oElm = document.getElementById("viewer");
        trace("oElm.innerHTML #2:"+oElm.innerHTML); //Shows empty.
    }, false);

    setTimeout(function() {

        var oElm = document.getElementById("viewer");
        trace("oElm.innerHTML #3:"+oElm.innerHTML); //Shows html content that is created after page loads.

        BorderChildNodes(document.body); //All the pdf content gets a border.

        var oElm = document.getElementById("pageContainer1");
        if(oElm)
        {
            oElm = GetElementByTagClass("div", "textLayer", oElm)
            if(oElm)
            {
                oElm.style.opacity = 1; //The textLayer is initially faded.

                var iTop = 543;
                var iLeft = 34;

                var oDiv = GetElementByXY(iLeft, iTop, oElm); //There are no IDs so we need to find what element to change by its location.
                if(oDiv)
                {
                    trace(oDiv.innerHTML);

                    var sInvoice = oDiv.innerHTML;

                    var sString = GM_getValue(sInvoice);

                    trace(sString);

                    oDiv.innerHTML += "<span style='font-weight:bold;color:black;'>&nbsp;"+sString+"</span>";
                }
            }
        }
    }, 5000);

}

function GetElementByXY(iX, iY, oParent)
{
    var childNodes = oParent.childNodes;

    for(var i = 0; i < childNodes.length; i++)
    {
        if((parseInt(childNodes[i].style.top) == iY)
        && (parseInt(childNodes[i].style.left) == iX)
        )
        {
            return childNodes[i];
        }
    }

    return null;
}

function GetElementByTagClass(sTag, sClass, oParent)
{
    if(oParent)
        var aElms = oParent.getElementsByTagName(sTag);
    else
       var aElms = document.getElementsByTagName(sTag);

    for(var i = 0; i < aElms.length; i++)
    {
        if(aElms[ i ].className.indexOf(sClass) > -1)
            return aElms[ i ];
    }

    return null;
}

function BorderChildNodes(oElm)
{
    var childNodes = oElm.childNodes;

    for(var i = 0; i < childNodes.length; i++)
    {
        if(childNodes[i].style)
           childNodes[i].style.border = "1px solid red";

        BorderChildNodes(childNodes[i]);
    }

    return true;
}

function trace(x) { setTimeout(function(){throw x}, 0) }

Problem is that textLayer is display:none in the @media print css. So my alterations do not appear in print preview.

Next I'll try adding divs to the document.body and try to position them in the right place.

§
Δημοσιεύτηκε: 26/09/2015
Επεξεργάστηκε: 26/09/2015

Awhile ago I made a POC UserScript to alter Firefox pdf.js. You can find the script here, but it I know off it only running in Scriptish because GM can't run on chrome-privileged pages.

Δημοσίευση απάντησης

Συνδεθείτε για να δημοσιεύσετε μια απάντηση.