parserOptions.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import {
  2. TextModes,
  3. ParserOptions,
  4. ElementNode,
  5. Namespaces,
  6. NodeTypes,
  7. isBuiltInType
  8. } from '@vue/compiler-core'
  9. import { makeMap, isVoidTag, isHTMLTag, isSVGTag } from '@vue/shared'
  10. import { TRANSITION, TRANSITION_GROUP } from './runtimeHelpers'
  11. import { decodeHtml } from './decodeHtml'
  12. import { decodeHtmlBrowser } from './decodeHtmlBrowser'
  13. const isRawTextContainer = /*#__PURE__*/ makeMap(
  14. 'style,iframe,script,noscript',
  15. true
  16. )
  17. export const enum DOMNamespaces {
  18. HTML = Namespaces.HTML,
  19. SVG,
  20. MATH_ML
  21. }
  22. export const parserOptions: ParserOptions = {
  23. isVoidTag,
  24. isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
  25. isPreTag: tag => tag === 'pre',
  26. decodeEntities: __BROWSER__ ? decodeHtmlBrowser : decodeHtml,
  27. isBuiltInComponent: (tag: string): symbol | undefined => {
  28. if (isBuiltInType(tag, `Transition`)) {
  29. return TRANSITION
  30. } else if (isBuiltInType(tag, `TransitionGroup`)) {
  31. return TRANSITION_GROUP
  32. }
  33. },
  34. // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
  35. getNamespace(tag: string, parent: ElementNode | undefined): DOMNamespaces {
  36. let ns = parent ? parent.ns : DOMNamespaces.HTML
  37. if (parent && ns === DOMNamespaces.MATH_ML) {
  38. if (parent.tag === 'annotation-xml') {
  39. if (tag === 'svg') {
  40. return DOMNamespaces.SVG
  41. }
  42. if (
  43. parent.props.some(
  44. a =>
  45. a.type === NodeTypes.ATTRIBUTE &&
  46. a.name === 'encoding' &&
  47. a.value != null &&
  48. (a.value.content === 'text/html' ||
  49. a.value.content === 'application/xhtml+xml')
  50. )
  51. ) {
  52. ns = DOMNamespaces.HTML
  53. }
  54. } else if (
  55. /^m(?:[ions]|text)$/.test(parent.tag) &&
  56. tag !== 'mglyph' &&
  57. tag !== 'malignmark'
  58. ) {
  59. ns = DOMNamespaces.HTML
  60. }
  61. } else if (parent && ns === DOMNamespaces.SVG) {
  62. if (
  63. parent.tag === 'foreignObject' ||
  64. parent.tag === 'desc' ||
  65. parent.tag === 'title'
  66. ) {
  67. ns = DOMNamespaces.HTML
  68. }
  69. }
  70. if (ns === DOMNamespaces.HTML) {
  71. if (tag === 'svg') {
  72. return DOMNamespaces.SVG
  73. }
  74. if (tag === 'math') {
  75. return DOMNamespaces.MATH_ML
  76. }
  77. }
  78. return ns
  79. },
  80. // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
  81. getTextMode({ tag, ns }: ElementNode): TextModes {
  82. if (ns === DOMNamespaces.HTML) {
  83. if (tag === 'textarea' || tag === 'title') {
  84. return TextModes.RCDATA
  85. }
  86. if (isRawTextContainer(tag)) {
  87. return TextModes.RAWTEXT
  88. }
  89. }
  90. return TextModes.DATA
  91. }
  92. }