Skip to content

Commit 5cf523d

Browse files
authored
Merge pull request #24 from siaikin/fix-broken-print
feat: 部分元素加载异常时不会中断打印
2 parents 11b364f + e3ebff1 commit 5cf523d

File tree

4 files changed

+35
-9
lines changed

4 files changed

+35
-9
lines changed

docs/examples/ComponentToPrint.vue

+9
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,15 @@ onMounted(() => {
141141
></video>
142142
</td>
143143
</tr>
144+
<tr>
145+
<td>Broken Image</td>
146+
<td>
147+
<img
148+
src="https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"
149+
width="200"
150+
/>
151+
</td>
152+
</tr>
144153
</tbody>
145154
</table>
146155
</div>

docs/examples/shadow-dom/ShadowDomToPrint.vue

+9
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,15 @@ onMounted(() => {
152152
></video>
153153
</td>
154154
</tr>
155+
<tr>
156+
<td>Broken Image</td>
157+
<td>
158+
<img
159+
src="https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"
160+
width="200"
161+
/>
162+
</td>
163+
</tr>
155164
</tbody>
156165
</table>
157166
</div>

src/components/vue-to-print/clone-node.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ function getChildNodes(dom: Node): Array<Node> {
105105
}
106106
}
107107

108-
export async function deepCloneNode(dom: Node): Promise<Node> {
108+
export async function deepCloneNode(dom: Node): Promise<{ node: Node; result: PromiseSettledResult<void>[]}> {
109109
const cloneMap = new Map<Node, Node>();
110110
const waitList: Array<Promise<void>> = [];
111111

@@ -140,7 +140,5 @@ export async function deepCloneNode(dom: Node): Promise<Node> {
140140
}
141141
}
142142

143-
await Promise.all(waitList);
144-
145-
return root;
143+
return { node: root, result: await Promise.allSettled(waitList) };
146144
}

src/components/vue-to-print/use-vue-to-print.ts

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { type Font, type PublicUseVueToPrintProps } from "./types";
22
import * as ShadowDomSupport from "./supports/shadow-dom";
33
import { deepCloneNode } from "./clone-node";
4-
import { isRef, toValue } from "vue";
4+
import { toValue } from "vue";
55

66
/**
77
* The default props in Vue are set within vueToPrintProps too.
@@ -202,8 +202,17 @@ export function useVueToPrint(props: PublicUseVueToPrintProps) {
202202
return;
203203
}
204204

205-
// React components can return a bare string as a valid JSX response
206-
const clonedContentNodes = await deepCloneNode(contentNodes);
205+
/**
206+
* Allow printing to continue even if some resources fail to load (e.g. bad image URLs, invalid fonts, etc.)
207+
*/
208+
const { node: clonedContentNodes, result } = await deepCloneNode(contentNodes);
209+
for (const promise of result) {
210+
if (promise.status === 'fulfilled') continue;
211+
logMessages([
212+
`An error occurred while cloning the content to print. Printing will continue, but some content may be missing.`,
213+
`Error: ${promise.reason}`,
214+
], "warning")
215+
}
207216
// const isText = clonedContentNodes instanceof Text;
208217

209218
const globalStyleLinkNodes = document.querySelectorAll("link[rel~='stylesheet']");
@@ -416,7 +425,8 @@ export function useVueToPrint(props: PublicUseVueToPrintProps) {
416425
};
417426

418427
const handleRemoveIframe = (force?: boolean) => {
419-
const { removeAfterPrint } = props;
428+
const removeAfterPrint = toValue(props.removeAfterPrint);
429+
420430

421431
if (force || removeAfterPrint) {
422432
// The user may have removed the iframe in `onAfterPrint`
@@ -428,7 +438,7 @@ export function useVueToPrint(props: PublicUseVueToPrintProps) {
428438
};
429439

430440
const logMessages = (messages: unknown[], level: "error" | "warning" | "debug" = "error") => {
431-
const { suppressErrors } = props;
441+
const suppressErrors = toValue(props.suppressErrors);
432442

433443
if (!suppressErrors) {
434444
if (level === "error") {

0 commit comments

Comments
 (0)