src/compiler/helpers.ts TYPESCRIPT 244 lines View on github.com → Search inside
1import { emptyObject } from 'shared/util'2import { ASTElement, ASTModifiers } from 'types/compiler'3import { parseFilters } from './parser/filter-parser'45type Range = { start?: number; end?: number }67/* eslint-disable no-unused-vars */8export function baseWarn(msg: string, range?: Range) {9  console.error(`[Vue compiler]: ${msg}`)10}11/* eslint-enable no-unused-vars */1213export function pluckModuleFunction<T, K extends keyof T>(14  modules: Array<T> | undefined,15  key: K16): Array<Exclude<T[K], undefined>> {17  return modules ? (modules.map(m => m[key]).filter(_ => _) as any) : []18}1920export function addProp(21  el: ASTElement,22  name: string,23  value: string,24  range?: Range,25  dynamic?: boolean26) {27  ;(el.props || (el.props = [])).push(28    rangeSetItem({ name, value, dynamic }, range)29  )30  el.plain = false31}3233export function addAttr(34  el: ASTElement,35  name: string,36  value: any,37  range?: Range,38  dynamic?: boolean39) {40  const attrs = dynamic41    ? el.dynamicAttrs || (el.dynamicAttrs = [])42    : el.attrs || (el.attrs = [])43  attrs.push(rangeSetItem({ name, value, dynamic }, range))44  el.plain = false45}4647// add a raw attr (use this in preTransforms)48export function addRawAttr(49  el: ASTElement,50  name: string,51  value: any,52  range?: Range53) {54  el.attrsMap[name] = value55  el.attrsList.push(rangeSetItem({ name, value }, range))56}5758export function addDirective(59  el: ASTElement,60  name: string,61  rawName: string,62  value: string,63  arg?: string,64  isDynamicArg?: boolean,65  modifiers?: ASTModifiers,66  range?: Range67) {68  ;(el.directives || (el.directives = [])).push(69    rangeSetItem(70      {71        name,72        rawName,73        value,74        arg,75        isDynamicArg,76        modifiers77      },78      range79    )80  )81  el.plain = false82}8384function prependModifierMarker(85  symbol: string,86  name: string,87  dynamic?: boolean88): string {89  return dynamic ? `_p(${name},"${symbol}")` : symbol + name // mark the event as captured90}9192export function addHandler(93  el: ASTElement,94  name: string,95  value: string,96  modifiers?: ASTModifiers | null,97  important?: boolean,98  warn?: Function,99  range?: Range,100  dynamic?: boolean101) {102  modifiers = modifiers || emptyObject103  // warn prevent and passive modifier104  /* istanbul ignore if */105  if (__DEV__ && warn && modifiers.prevent && modifiers.passive) {106    warn(107      "passive and prevent can't be used together. " +108        "Passive handler can't prevent default event.",109      range110    )111  }112113  // normalize click.right and click.middle since they don't actually fire114  // this is technically browser-specific, but at least for now browsers are115  // the only target envs that have right/middle clicks.116  if (modifiers.right) {117    if (dynamic) {118      name = `(${name})==='click'?'contextmenu':(${name})`119    } else if (name === 'click') {120      name = 'contextmenu'121      delete modifiers.right122    }123  } else if (modifiers.middle) {124    if (dynamic) {125      name = `(${name})==='click'?'mouseup':(${name})`126    } else if (name === 'click') {127      name = 'mouseup'128    }129  }130131  // check capture modifier132  if (modifiers.capture) {133    delete modifiers.capture134    name = prependModifierMarker('!', name, dynamic)135  }136  if (modifiers.once) {137    delete modifiers.once138    name = prependModifierMarker('~', name, dynamic)139  }140  /* istanbul ignore if */141  if (modifiers.passive) {142    delete modifiers.passive143    name = prependModifierMarker('&', name, dynamic)144  }145146  let events147  if (modifiers.native) {148    delete modifiers.native149    events = el.nativeEvents || (el.nativeEvents = {})150  } else {151    events = el.events || (el.events = {})152  }153154  const newHandler: any = rangeSetItem({ value: value.trim(), dynamic }, range)155  if (modifiers !== emptyObject) {156    newHandler.modifiers = modifiers157  }158159  const handlers = events[name]160  /* istanbul ignore if */161  if (Array.isArray(handlers)) {162    important ? handlers.unshift(newHandler) : handlers.push(newHandler)163  } else if (handlers) {164    events[name] = important ? [newHandler, handlers] : [handlers, newHandler]165  } else {166    events[name] = newHandler167  }168169  el.plain = false170}171172export function getRawBindingAttr(el: ASTElement, name: string) {173  return (174    el.rawAttrsMap[':' + name] ||175    el.rawAttrsMap['v-bind:' + name] ||176    el.rawAttrsMap[name]177  )178}179180export function getBindingAttr(181  el: ASTElement,182  name: string,183  getStatic?: boolean184): string | undefined {185  const dynamicValue =186    getAndRemoveAttr(el, ':' + name) || getAndRemoveAttr(el, 'v-bind:' + name)187  if (dynamicValue != null) {188    return parseFilters(dynamicValue)189  } else if (getStatic !== false) {190    const staticValue = getAndRemoveAttr(el, name)191    if (staticValue != null) {192      return JSON.stringify(staticValue)193    }194  }195}196197// note: this only removes the attr from the Array (attrsList) so that it198// doesn't get processed by processAttrs.199// By default it does NOT remove it from the map (attrsMap) because the map is200// needed during codegen.201export function getAndRemoveAttr(202  el: ASTElement,203  name: string,204  removeFromMap?: boolean205): string | undefined {206  let val207  if ((val = el.attrsMap[name]) != null) {208    const list = el.attrsList209    for (let i = 0, l = list.length; i < l; i++) {210      if (list[i].name === name) {211        list.splice(i, 1)212        break213      }214    }215  }216  if (removeFromMap) {217    delete el.attrsMap[name]218  }219  return val220}221222export function getAndRemoveAttrByRegex(el: ASTElement, name: RegExp) {223  const list = el.attrsList224  for (let i = 0, l = list.length; i < l; i++) {225    const attr = list[i]226    if (name.test(attr.name)) {227      list.splice(i, 1)228      return attr229    }230  }231}232233function rangeSetItem(item: any, range?: { start?: number; end?: number }) {234  if (range) {235    if (range.start != null) {236      item.start = range.start237    }238    if (range.end != null) {239      item.end = range.end240    }241  }242  return item243}

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.