| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- import {
- AttributeNode,
- createSimpleExpression,
- ExpressionNode,
- NodeTransform,
- NodeTypes,
- SourceLocation,
- TransformContext
- } from '@vue/compiler-core'
- import { isRelativeUrl, parseUrl } from './templateUtils'
- export interface AssetURLOptions {
- [name: string]: string[]
- }
- const defaultOptions: AssetURLOptions = {
- video: ['src', 'poster'],
- source: ['src'],
- img: ['src'],
- image: ['xlink:href', 'href'],
- use: ['xlink:href', 'href']
- }
- export const createAssetUrlTransformWithOptions = (
- options: AssetURLOptions
- ): NodeTransform => {
- const mergedOptions = {
- ...defaultOptions,
- ...options
- }
- return (node, context) =>
- (transformAssetUrl as Function)(node, context, mergedOptions)
- }
- export const transformAssetUrl: NodeTransform = (
- node,
- context,
- options: AssetURLOptions = defaultOptions
- ) => {
- if (node.type === NodeTypes.ELEMENT) {
- for (const tag in options) {
- if ((tag === '*' || node.tag === tag) && node.props.length) {
- const attributes = options[tag]
- attributes.forEach(item => {
- node.props.forEach((attr: AttributeNode, index) => {
- if (attr.type !== NodeTypes.ATTRIBUTE) return
- if (attr.name !== item) return
- if (!attr.value) return
- if (!isRelativeUrl(attr.value.content)) return
- const url = parseUrl(attr.value.content)
- const exp = getImportsExpressionExp(
- url.path,
- url.hash,
- attr.loc,
- context
- )
- node.props[index] = {
- type: NodeTypes.DIRECTIVE,
- name: 'bind',
- arg: createSimpleExpression(item, true, attr.loc),
- exp,
- modifiers: [],
- loc: attr.loc
- }
- })
- })
- }
- }
- }
- }
- function getImportsExpressionExp(
- path: string | undefined,
- hash: string | undefined,
- loc: SourceLocation,
- context: TransformContext
- ): ExpressionNode {
- if (path) {
- const importsArray = Array.from(context.imports)
- const existing = importsArray.find(i => i.path === path)
- if (existing) {
- return existing.exp as ExpressionNode
- }
- const name = `_imports_${importsArray.length}`
- const exp = createSimpleExpression(name, false, loc, true)
- context.imports.add({ exp, path })
- if (hash && path) {
- return context.hoist(
- createSimpleExpression(`${name} + '${hash}'`, false, loc, true)
- )
- } else {
- return exp
- }
- } else {
- return createSimpleExpression(`''`, false, loc, true)
- }
- }
|