import { NativeLoadFontFaceFail, NativeLoadFontFaceOptions, appLoadFontFace, getCurrentPage, } from '@dcloudio/uni-runtime' import { LoadFontFaceErrCode, LoadFontFaceOptions, LoadFontFaceSuccess, } from '../interface.uts' import { LoadFontFaceFailImpl } from '../unierror.uts' export const loadFontFace = defineAsyncApi< LoadFontFaceOptions, LoadFontFaceSuccess >('loadFontFace', (options: LoadFontFaceOptions, res: ApiExecutor) => { if (options.global == true) { if (checkOptionSource(options, res)) { appLoadFontFace(getLoadFontFaceOptions(options, res)) } } else { const page = getCurrentPage() if (page === null) { res.reject(new LoadFontFaceFailImpl('page is not ready', 99)) return } if (page.$fontFamilySet.has(options.family)) { return } if (checkOptionSource(options, res)) { page.$fontFamilySet.add(options.family) appLoadFontFace(getLoadFontFaceOptions(options, res)) } } }) const SOURCE_REG = /(.+\.((ttf)|(otf)|(woff2?))$)|(^(http|https):\/\/.+)|(^(data:font).+)/ function checkOptionSource( options: LoadFontFaceOptions, res: ApiExecutor, ): boolean { options.source = removeUrlWrap(options.source) if (!SOURCE_REG.test(options.source)) { res.reject( new LoadFontFaceFailImpl( 'loadFontFace:fail, source is invalid.', 101, ), ) return false } return true } function removeUrlWrap(source: string): string { if (source.startsWith('url(')) { // url("xxx") format("xxx") 时移除 format("xxx") const FormatParts = source.split('format(') if (FormatParts.length > 1) { source = FormatParts[0].trim() } source = source.substring(4, source.length - 1) } if (source.startsWith('"') || source.startsWith("'")) { source = source.substring(1, source.length - 1) } return source } function getLoadFontFaceOptions( options: LoadFontFaceOptions, res: ApiExecutor, ): NativeLoadFontFaceOptions { return { family: options.family, source: options.source, success: (_: any | null) => { res.resolve(null) }, fail: (error: NativeLoadFontFaceFail) => { res.reject( new LoadFontFaceFailImpl( error.errMsg, error.errCode as LoadFontFaceErrCode, ), ) }, } as NativeLoadFontFaceOptions }