f82f3d2abb53903ce39b2a950cbf20029d66a089799b6d5a6889a2f1fe25f5bf27c7fe9ee3b9649cf8888ac5e939d21245c4e419b7249052858b427b54edce 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /* @flow */
  2. import { makeMap } from 'shared/util'
  3. // these are reserved for web because they are directly compiled away
  4. // during template compilation
  5. export const isReservedAttr = makeMap('style,class')
  6. // attributes that should be using props for binding
  7. const acceptValue = makeMap('input,textarea,option,select,progress')
  8. export const mustUseProp = (tag: string, type: ?string, attr: string): boolean => {
  9. return (
  10. (attr === 'value' && acceptValue(tag)) && type !== 'button' ||
  11. (attr === 'selected' && tag === 'option') ||
  12. (attr === 'checked' && tag === 'input') ||
  13. (attr === 'muted' && tag === 'video')
  14. )
  15. }
  16. export const isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck')
  17. const isValidContentEditableValue = makeMap('events,caret,typing,plaintext-only')
  18. export const convertEnumeratedValue = (key: string, value: any) => {
  19. return isFalsyAttrValue(value) || value === 'false'
  20. ? 'false'
  21. // allow arbitrary string value for contenteditable
  22. : key === 'contenteditable' && isValidContentEditableValue(value)
  23. ? value
  24. : 'true'
  25. }
  26. export const isBooleanAttr = makeMap(
  27. 'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
  28. 'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +
  29. 'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +
  30. 'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +
  31. 'required,reversed,scoped,seamless,selected,sortable,translate,' +
  32. 'truespeed,typemustmatch,visible'
  33. )
  34. export const xlinkNS = 'http://www.w3.org/1999/xlink'
  35. export const isXlink = (name: string): boolean => {
  36. return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink'
  37. }
  38. export const getXlinkProp = (name: string): string => {
  39. return isXlink(name) ? name.slice(6, name.length) : ''
  40. }
  41. export const isFalsyAttrValue = (val: any): boolean => {
  42. return val == null || val === false
  43. }