Skip to content

Commit

Permalink
fix: safari not use web worker fetch resource(exists blob:null error)
Browse files Browse the repository at this point in the history
  • Loading branch information
qq15725 committed May 5, 2023
1 parent 5250038 commit 0b4ec02
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 31 deletions.
4 changes: 2 additions & 2 deletions src/converts/dom-to-canvas.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createStyleElement, orCreateContext } from '../create-context'
import { createImage, svgToDataUrl, xmlns } from '../utils'
import { XMLNS, createImage, svgToDataUrl } from '../utils'
import { imageToCanvas } from '../image-to-canvas'
import { domToForeignObjectSvg } from './dom-to-foreign-object-svg'

Expand All @@ -14,7 +14,7 @@ export async function domToCanvas(node: any, options?: any) {
const dataUrl = svgToDataUrl(svg)
if (!context.autoDestruct) {
context.svgStyleElement = createStyleElement(context.ownerDocument)
context.svgDefsElement = context.ownerDocument?.createElementNS(xmlns, 'defs')
context.svgDefsElement = context.ownerDocument?.createElementNS(XMLNS, 'defs')
context.svgStyles.clear()
}
const image = createImage(dataUrl, svg.ownerDocument)
Expand Down
36 changes: 22 additions & 14 deletions src/create-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { getDefaultRequestInit } from './get-default-request-init'
import {
IN_BROWSER,
SUPPORT_WEB_WORKER,
XMLNS,
consoleWarn,
isContext,
isElementNode,
supportWebp, waitUntilLoad, xmlns,
supportWebp,
waitUntilLoad,
} from './utils'
import type { Context, Request } from './context'
import type { Options } from './options'
Expand Down Expand Up @@ -63,7 +66,7 @@ export async function createContext<T extends Node>(node: T, options?: Options &
ownerWindow,
dpi: scale === 1 ? null : 96 * scale,
svgStyleElement: createStyleElement(ownerDocument),
svgDefsElement: ownerDocument?.createElementNS(xmlns, 'defs'),
svgDefsElement: ownerDocument?.createElementNS(XMLNS, 'defs'),
svgStyles: new Map<string, string[]>(),
defaultComputedStyles: new Map<string, Record<string, any>>(),
workers: [
Expand All @@ -73,21 +76,26 @@ export async function createContext<T extends Node>(node: T, options?: Options &
: 0,
),
].map(() => {
const worker = new Worker(workerUrl!)
worker.onmessage = async event => {
const { url, result } = event.data
if (result) {
requests.get(url)?.resovle?.(result)
} else {
try {
const worker = new Worker(workerUrl!)
worker.onmessage = async event => {
const { url, result } = event.data
if (result) {
requests.get(url)?.resovle?.(result)
} else {
requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${ url }`))
}
}
worker.onmessageerror = event => {
const { url } = event.data
requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${ url }`))
}
return worker
} catch (error) {
consoleWarn('Failed to new Worker', error)
return null
}
worker.onmessageerror = event => {
const { url } = event.data
requests.get(url)?.reject?.(new Error(`Error receiving message from worker: ${ url }`))
}
return worker
}),
}).filter(Boolean) as any,
fontFamilies: new Set<string>(),
fontCssTexts: new Map<string, string>(),
acceptOfImage: `${ [
Expand Down
2 changes: 1 addition & 1 deletion src/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export function contextFetch(context: Context, options: ContextFetchOptions) {
}

request.response = (
rawUrl.startsWith('http') && workers.length
!IN_SAFARI && rawUrl.startsWith('http') && workers.length
? new Promise((resolve, reject) => {
const worker = workers[requests.size & (workers.length - 1)]
worker.postMessage({ rawUrl, ...baseFetchOptions })
Expand Down
28 changes: 16 additions & 12 deletions src/get-default-style.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isSVGElementNode, uuid } from './utils'
import { XMLNS, consoleWarn, isSVGElementNode, uuid } from './utils'
import type { Context } from './context'

const ignoredStyles = [
Expand Down Expand Up @@ -39,16 +39,20 @@ export function getDefaultStyle(

let sandbox = context.sandbox
if (!sandbox) {
if (ownerDocument) {
sandbox = ownerDocument.createElement('iframe')
sandbox.id = `__SANDBOX__-${ uuid() }`
sandbox.width = '0'
sandbox.height = '0'
sandbox.style.visibility = 'hidden'
sandbox.style.position = 'fixed'
ownerDocument.body.appendChild(sandbox)
sandbox.contentWindow?.document.write('<!DOCTYPE html><meta charset="UTF-8"><title></title><body>')
context.sandbox = sandbox
try {
if (ownerDocument) {
sandbox = ownerDocument.createElement('iframe')
sandbox.id = `__SANDBOX__-${ uuid() }`
sandbox.width = '0'
sandbox.height = '0'
sandbox.style.visibility = 'hidden'
sandbox.style.position = 'fixed'
ownerDocument.body.appendChild(sandbox)
sandbox.contentWindow?.document.write('<!DOCTYPE html><meta charset="UTF-8"><title></title><body>')
context.sandbox = sandbox
}
} catch (error) {
consoleWarn('Failed to create iframe sandbox', error)
}
}
if (!sandbox) return {}
Expand All @@ -60,7 +64,7 @@ export function getDefaultStyle(
let root: HTMLElement | SVGSVGElement
let el: Element
if (isSvgNode) {
root = sandboxDocument.createElementNS('http://www.w3.org/2000/svg', 'svg')
root = sandboxDocument.createElementNS(XMLNS, 'svg')
el = root.ownerDocument.createElementNS(root.namespaceURI, nodeName)
attributes.forEach(([name, value]) => {
el.setAttributeNS(null, name!, value!)
Expand Down
4 changes: 2 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ export function getDocument<T extends Node>(target?: T | null): Document {
) as any
}

export const xmlns = 'http://www.w3.org/2000/svg'
export const XMLNS = 'http://www.w3.org/2000/svg'

export function createSvg(width: number, height: number, ownerDocument?: Document | null): SVGSVGElement {
const svg = getDocument(ownerDocument).createElementNS(xmlns, 'svg')
const svg = getDocument(ownerDocument).createElementNS(XMLNS, 'svg')
svg.setAttributeNS(null, 'width', width.toString())
svg.setAttributeNS(null, 'height', height.toString())
svg.setAttributeNS(null, 'viewBox', `0 0 ${ width } ${ height }`)
Expand Down

1 comment on commit 0b4ec02

@vercel
Copy link

@vercel vercel bot commented on 0b4ec02 May 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

modern-screenshot – ./

modern-screenshot.vercel.app
modern-screenshot-git-main-qq15725.vercel.app
modern-screenshot-qq15725.vercel.app

Please sign in to comment.