parserOptionsMinimal.ts 2.1 KB

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