Closed john-pellegrini closed 4 days ago
Hey there. Could you share your setup please (a Codesandbox or similar would be ideal)? We do inject the doctype into the HTML of the iframe being printed, but not sure how it could be actually displaying for you
Actually when I'm running/developing the react app on my local machine I don't see the "doctype" in the print dialog window. This only happened when the code was pushed to our test servers. I'm happy to share what ever you think could be helpful, but it's a very large react app so when you say "setup" what specifically would help you? thank you This is the component where I've added the useReactToPrint hook: viewScreen.txt
Thanks! Do you know if your custom print
function is getting used in this case? If so, could you share the customToPrint
function's implementation?
I'm using the "custom" print function in one of the pages I'm implementing the print functionality, however it shows the doc type in the other 2 as well. This is my custom function:
const customToPrint = (printWindow: HTMLIFrameElement): Promise<void> => {
const printContent = printWindow.contentDocument || printWindow.contentWindow?.document;
const printedScrollContainerList = printContent?.querySelectorAll('.MuiDataGrid-virtualScroller');
const originScrollContainerList = document.querySelectorAll('.MuiDataGrid-virtualScroller');
if (!printedScrollContainerList || !originScrollContainerList) {
return Promise.resolve();
}
const getScrollHeaderText = (scrollContainer: Element): string | null | undefined =>
scrollContainer
.closest('div[data-testid="layout-gadget-grid"]')
?.querySelector('div[class*="-header"] > span')?.textContent;
const originScrollContainerRecords: Record<string, Element> = Array.from(originScrollContainerList).reduce(
(acc, scroll) => {
const scrollHeaderText = getScrollHeaderText(scroll);
scrollHeaderText && (acc[scrollHeaderText] = scroll);
return acc;
},
{},
);
Array.from(printedScrollContainerList).forEach((printedScrollContainer) => {
const scrollHeaderText = getScrollHeaderText(printedScrollContainer);
scrollHeaderText &&
printedScrollContainer?.scrollTo(0, Number(originScrollContainerRecords[scrollHeaderText]?.scrollTop));
});
printWindow?.contentWindow?.print();
// print must return a Promise
return Promise.resolve();
};
@MatthewHerbst - if you have any idea how the doctype declaration could be added to the body tag please let me know? Thanks
I'm truly not sure. I've tested the code we run and in Chrome 126 on my machine it does not do that:
const printWindow = document.createElement("iframe");
printWindow.srcdoc = "<!DOCTYPE html>";
which gives
What stands out to me looking at your code in the image above is that it seems the srcdoc
property on your iframe isn't correct. It has srcdoc="<!DOCTYPE html>"
when it should be srcdoc="<!DOCTYPE html>"
Do you have some sort of safety encoding going on or something? <
is the code for <
and >
is the code for >
.
Ok thank you for checking - it's working fine for me locally as well, but once the code gets pushed to our test servers this issue occurs. Like you said it seems there's some additional encoding occurring for some reason. (frustrating) Another quick question? Is there a way to access the print window other then in the "print" api function? I'm trying to come up with a "hack" to prevent this but I don't want to create a "custom" print function for every component
Is there a way to access the print window other then in the "print" api function?
If you ensure that removeAfterPrint: false
is set on the printing options then after the print is run the printing iframe (with ID of "printWindow"
) should still be in your DOM and you can inspect it directly. The iframe will be replaced the next time you click print.
(In v3 of this lib which I'm working on we remove it by default and preserving it is opt-in, but for now it's preserved by default since that's been the behavior for years and changing that would be a breaking change)
Regarding the encoding, do you have a script on your page maybe that's trying to make sure all added code has tags removed to prevent execution? For example, you might be trying to prevent folks from injecting <script>badFunction()</script>
type things, though I've never seen something be so encompassing as to detect setting a random property on a runtime-only iframe
@MatthewHerbst - thank you again for your responses. I'm checking with others to see if there aware of anything that might be causing this to happen
@john-pellegrini did you ever get to the bottom of this issue?
Unfortunately we weren't able to figure why this was happening, so I'm using onBeforePrint() callback function to remove the node from the DOM
Thanks for the update! Will close this for now, please feel free to re-open if there's something more you think react-to-print
can do to help here
Hi, I'm getting the <!DOCTYPE html> declaration included in the print content: Any ideas on what might be causing this to happen? Thank you for your help