Press n or j to go to the next uncovered block, b, p or k for the previous block.
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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | 8x 8x 8x 8x 8x 8x 8x 5x 44x 8x 135x 93x 51x 99x 48x 48x 48x 44x 88x 88x 44x 80x 80x 8x 8x 44x 56x 44x 10x 34x 8x 8x 8x 14x 14x 13x 1x 8x 8x 26x 26x 46x 45x 45x 45x 46x 45x 40x 5x 5x 45x 1x 1x 46x 46x 9x 37x 20x 17x 11x 26x 26x 26x | import path from 'path' import { ConstantTypes, createCompoundExpression, createSimpleExpression, NodeTransform, NodeTypes, SimpleExpressionNode } from '@vue/compiler-core' import { isRelativeUrl, parseUrl, isExternalUrl, isDataUrl } from './templateUtils' import { AssetURLOptions, defaultAssetUrlOptions } from './templateTransformAssetUrl' const srcsetTags = ['img', 'source'] interface ImageCandidate { url: string descriptor: string } // http://w3c.github.io/html/semantics-embedded-content.html#ref-for-image-candidate-string-5 const escapedSpaceCharacters = /( |\\t|\\n|\\f|\\r)+/g export const createSrcsetTransformWithOptions = ( options: Required<AssetURLOptions> ): NodeTransform => { return (node, context) => (transformSrcset as Function)(node, context, options) } export const transformSrcset: NodeTransform = ( node, context, options: Required<AssetURLOptions> = defaultAssetUrlOptions ) => { if (node.type === NodeTypes.ELEMENT) { if (srcsetTags.includes(node.tag) && node.props.length) { node.props.forEach((attr, index) => { if (attr.name === 'srcset' && attr.type === NodeTypes.ATTRIBUTE) { Iif (!attr.value) return const value = attr.value.content if (!value) return const imageCandidates: ImageCandidate[] = value.split(',').map(s => { // The attribute value arrives here with all whitespace, except // normal spaces, represented by escape sequences const [url, descriptor] = s .replace(escapedSpaceCharacters, ' ') .trim() .split(' ', 2) return { url, descriptor } }) // data urls contains comma after the encoding so we need to re-merge // them for (let i = 0; i < imageCandidates.length; i++) { const { url } = imageCandidates[i] if (isDataUrl(url)) { imageCandidates[i + 1].url = url + ',' + imageCandidates[i + 1].url imageCandidates.splice(i, 1) } } const hasQualifiedUrl = imageCandidates.some(({ url }) => { return ( !isExternalUrl(url) && !isDataUrl(url) && (options.includeAbsolute || isRelativeUrl(url)) ) }) // When srcset does not contain any qualified URLs, skip transforming if (!hasQualifiedUrl) { return } if (options.base) { const base = options.base const set: string[] = [] imageCandidates.forEach(({ url, descriptor }) => { descriptor = descriptor ? ` ${descriptor}` : `` if (isRelativeUrl(url)) { set.push((path.posix || path).join(base, url) + descriptor) } else { set.push(url + descriptor) } }) attr.value.content = set.join(', ') return } const compoundExpression = createCompoundExpression([], attr.loc) imageCandidates.forEach(({ url, descriptor }, index) => { if ( !isExternalUrl(url) && !isDataUrl(url) && (options.includeAbsolute || isRelativeUrl(url)) ) { const { path } = parseUrl(url) let exp: SimpleExpressionNode if (path) { const existingImportsIndex = context.imports.findIndex( i => i.path === path ) if (existingImportsIndex > -1) { exp = createSimpleExpression( `_imports_${existingImportsIndex}`, false, attr.loc, ConstantTypes.CAN_STRINGIFY ) } else { exp = createSimpleExpression( `_imports_${context.imports.length}`, false, attr.loc, ConstantTypes.CAN_STRINGIFY ) context.imports.push({ exp, path }) } compoundExpression.children.push(exp) } } else { const exp = createSimpleExpression( `"${url}"`, false, attr.loc, ConstantTypes.CAN_STRINGIFY ) compoundExpression.children.push(exp) } const isNotLast = imageCandidates.length - 1 > index if (descriptor && isNotLast) { compoundExpression.children.push(` + ' ${descriptor}, ' + `) } else if (descriptor) { compoundExpression.children.push(` + ' ${descriptor}'`) } else if (isNotLast) { compoundExpression.children.push(` + ', ' + `) } }) const hoisted = context.hoist(compoundExpression) hoisted.constType = ConstantTypes.CAN_STRINGIFY node.props[index] = { type: NodeTypes.DIRECTIVE, name: 'bind', arg: createSimpleExpression('srcset', true, attr.loc), exp: hoisted, modifiers: [], loc: attr.loc } } }) } } } |