Skip to content

Commit

Permalink
feat(loadResource): 支持 hook、jsText、cssText
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Jul 30, 2021
1 parent 4e944ac commit b39a549
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 18 deletions.
45 changes: 42 additions & 3 deletions src/utils/loadResource.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,56 @@ describe('loadResource', () => {
expect(document.documentElement.outerHTML).not.toInclude(src)
})

test('支持 hook', async () => {
test('支持全局 hook', async () => {
const src = 'http://foo.bar/this-is-an-image.js'
await loadResource(
{
type: LoadResourceUrlType.js,
path: src,
},
{
hook: el => {
el.dataset.hooked = '1111'
},
},
)
expect(
document.documentElement.querySelector(`[data-hooked="1111"]`)!.tagName,
).toBe('SCRIPT')
})

test('支持局部 hook', async () => {
const src = 'http://foo.bar/this-is-an-image.js'
await loadResource({
type: LoadResourceUrlType.js,
path: src,
hook: el => {
el.dataset.hooked = '1'
el.dataset.hooked = '2222'
},
})
expect(
document.documentElement.querySelector(`[data-hooked="1"]`)!.tagName,
document.documentElement.querySelector(`[data-hooked="2222"]`)!.tagName,
).toBe('SCRIPT')
})

test('可加载 js 代码文本', async () => {
const code = 'window.__x__ = 1'
const [el] = await loadResource({
type: LoadResourceUrlType.jsText,
path: code,
})
expect(el.tagName).toBe('SCRIPT')
expect(el.textContent).toBe(code)
expect((window as any).__x__).toBe(1)
})

test('可加载 css 样式文本', async () => {
const code = 'body { font-size: 20px; }'
const [el] = await loadResource({
type: LoadResourceUrlType.cssText,
path: code,
})
expect(el.tagName).toBe('STYLE')
expect(el.textContent).toBe(code)
})
})
84 changes: 69 additions & 15 deletions src/utils/loadResource.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { castArray } from 'lodash-uni'
export type LoadResourceElement =
| HTMLScriptElement
| HTMLLinkElement
| HTMLStyleElement
| HTMLImageElement

/**
* 资源类型。
Expand All @@ -9,13 +13,21 @@ export enum LoadResourceUrlType {
/** 样式资源 */
css = 'css',

/** 样式文本 */
cssText = 'cssText',

/** 代码资源 */
js = 'js',

/** 代码文本 */
jsText = 'jsText',

/** 图片资源 */
img = 'img',
}

export type LoadResourceHook = (el: LoadResourceElement) => any

/**
* 资源地址。
*
Expand All @@ -32,28 +44,58 @@ export interface LoadResourceUrl {
alternatePath?: string

/** 钩子 */
hook?: (el: HTMLScriptElement | HTMLLinkElement | HTMLImageElement) => any
hook?: LoadResourceHook
}

export interface LoadResourceOptions {
/** 钩子 */
hook?: LoadResourceHook
}

function loadSpecificResource(
url: LoadResourceUrl,
): Promise<HTMLScriptElement | HTMLLinkElement | HTMLImageElement> {
): Promise<LoadResourceElement> {
return new Promise((resolve, reject) => {
let el!: HTMLScriptElement | HTMLLinkElement | HTMLImageElement
let el!: LoadResourceElement
switch (url.type) {
case LoadResourceUrlType.js:
el = document.createElement('script')
el.src = url.path
el.async = true
{
const _el = document.createElement('script')
_el.src = url.path
_el.async = true
el = _el
}
break
case LoadResourceUrlType.jsText:
{
const _el = document.createElement('script')
_el.setAttribute('type', 'text/javascript')
_el.textContent = url.path
el = _el
}
break
case LoadResourceUrlType.css:
el = document.createElement('link')
el.rel = 'stylesheet'
el.href = url.path
{
const _el = document.createElement('link')
_el.rel = 'stylesheet'
_el.href = url.path
el = _el
}
break
case LoadResourceUrlType.cssText:
{
const _el = document.createElement('style')
_el.setAttribute('type', 'text/css')
_el.textContent = url.path
el = _el
}
break
case LoadResourceUrlType.img:
el = document.createElement('img')
el.src = url.path
{
const _el = document.createElement('img')
_el.src = url.path
el = _el
}
break
/* istanbul ignore next */
default:
Expand Down Expand Up @@ -84,6 +126,7 @@ function loadSpecificResource(
*
* @public
* @param url 要加载的资源地址
* @param options 选项
* @returns 返回各资源的 HTML 元素组成的数组
* @example
* ```typescript
Expand All @@ -103,8 +146,9 @@ function loadSpecificResource(
*/
export function loadResource(
url: string | LoadResourceUrl | Array<string | LoadResourceUrl>,
): Promise<Array<HTMLScriptElement | HTMLLinkElement | HTMLImageElement>> {
const urls = castArray(url).map<LoadResourceUrl>(item => {
options?: LoadResourceOptions,
): Promise<Array<LoadResourceElement>> {
const urls = (Array.isArray(url) ? url : [url]).map<LoadResourceUrl>(item => {
return !(typeof item === 'string')
? item
: {
Expand All @@ -116,5 +160,15 @@ export function loadResource(
path: item,
}
})
return Promise.all(urls.map(url => loadSpecificResource(url)))
return Promise.all(
urls.map(url =>
loadSpecificResource({
...url,
hook: el => {
options?.hook?.(el)
url.hook?.(el)
},
}),
),
)
}

0 comments on commit b39a549

Please sign in to comment.