index.uts 2.4 KB
Newer Older
DCloud-yyl's avatar
DCloud-yyl 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
import {
    NativeLoadFontFaceFail,
    NativeLoadFontFaceOptions,
    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)) {
            getApp().$nativeApp!.loadFontFace(
                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)
            page.$nativePage!.loadFontFace(getLoadFontFaceOptions(options, res))
        }
    }
})

const SOURCE_REG = /(.+\.((ttf)|(otf)|(woff2?))$)|(^(http|https):\/\/.+)/
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(')) {
        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
}