]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: getting ready for textmode handling
authorEvan You <yyx990803@gmail.com>
Thu, 16 Nov 2023 08:28:56 +0000 (16:28 +0800)
committerEvan You <yyx990803@gmail.com>
Sat, 25 Nov 2023 08:18:29 +0000 (16:18 +0800)
packages/compiler-core/src/parser/Tokenizer.ts
packages/compiler-core/src/parser/index.ts
packages/compiler-dom/src/parserOptions.ts

index 214817a425bc4db41fc970e2292ccb669d45f347..775ea584262f83948cd52df800b0d05b4f88f8c4 100644 (file)
@@ -65,8 +65,8 @@ export const enum CharCodes {
   RightSquare = 93 // "]"
 }
 
-const defaultDelimitersOpen = [123, 123] // "{{"
-const defaultDelimitersClose = [125, 125] // "}}"
+const defaultDelimitersOpen = new Uint8Array([123, 123]) // "{{"
+const defaultDelimitersClose = new Uint8Array([125, 125]) // "}}"
 
 /** All the states the tokenizer can be in. */
 const enum State {
@@ -115,6 +115,17 @@ const enum State {
   InEntity
 }
 
+/**
+ * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a
+ * tag name.
+ */
+function isTagStartChar(c: number): boolean {
+  return (
+    (c >= CharCodes.LowerA && c <= CharCodes.LowerZ) ||
+    (c >= CharCodes.UpperA && c <= CharCodes.UpperZ)
+  )
+}
+
 export function isWhitespace(c: number): boolean {
   return (
     c === CharCodes.Space ||
@@ -261,9 +272,9 @@ export default class Tokenizer {
     }
   }
 
-  public delimiterOpen: number[] = defaultDelimitersOpen
-  public delimiterClose: number[] = defaultDelimitersClose
-  private matchDelimiter(c: number, delimiter: number[]): boolean {
+  public delimiterOpen: Uint8Array = defaultDelimitersOpen
+  public delimiterClose: Uint8Array = defaultDelimitersClose
+  private matchDelimiter(c: number, delimiter: Uint8Array): boolean {
     if (c === delimiter[0]) {
       const l = delimiter.length
       for (let i = 1; i < l; i++) {
@@ -420,16 +431,6 @@ export default class Tokenizer {
     }
   }
 
-  /**
-   * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.
-   */
-  private isTagStartChar(c: number) {
-    return (
-      (c >= CharCodes.LowerA && c <= CharCodes.LowerZ) ||
-      (c >= CharCodes.UpperA && c <= CharCodes.UpperZ)
-    )
-  }
-
   private startSpecial(sequence: Uint8Array, offset: number) {
     this.isSpecial = true
     this.currentSequence = sequence
@@ -444,7 +445,7 @@ export default class Tokenizer {
     } else if (c === CharCodes.Questionmark) {
       this.state = State.InProcessingInstruction
       this.sectionStart = this.index + 1
-    } else if (this.isTagStartChar(c)) {
+    } else if (isTagStartChar(c)) {
       const lower = c | 0x20
       this.sectionStart = this.index
       if (lower === Sequences.TitleEnd[2]) {
@@ -476,7 +477,7 @@ export default class Tokenizer {
     } else if (c === CharCodes.Gt) {
       this.state = State.Text
     } else {
-      this.state = this.isTagStartChar(c)
+      this.state = isTagStartChar(c)
         ? State.InClosingTagName
         : State.InSpecialComment
       this.sectionStart = this.index
index 585af7e0d42844f435eafd2e70aa528e184082dc..f6df84a2654dcf573ff4bd9605f1b441bafd2d2c 100644 (file)
@@ -19,9 +19,9 @@ import { CompilerCompatOptions } from '../compat/compatConfig'
 import { NO, extend } from '@vue/shared'
 import { defaultOnError, defaultOnWarn } from '../errors'
 import { isCoreComponent } from '../utils'
+import { TextModes } from '../parse'
 
 type OptionalOptions =
-  | 'getTextMode' // TODO
   | 'whitespace'
   | 'isNativeTag'
   | 'isBuiltInComponent'
@@ -45,7 +45,7 @@ const decodeMap: Record<string, string> = {
 export const defaultParserOptions: MergedParserOptions = {
   delimiters: [`{{`, `}}`],
   getNamespace: () => Namespaces.HTML,
-  // getTextMode: () => TextModes.DATA,
+  getTextMode: () => TextModes.DATA,
   isVoidTag: NO,
   isPreTag: NO,
   isCustomElement: NO,
@@ -598,8 +598,12 @@ function reset() {
   stack.length = 0
 }
 
-function toCharCodes(str: string): number[] {
-  return str.split('').map(c => c.charCodeAt(0))
+function toCharCodes(str: string): Uint8Array {
+  const ret = new Uint8Array()
+  for (let i = 0; i < str.length; i++) {
+    ret[i] = str.charCodeAt(i)
+  }
+  return ret
 }
 
 export function baseParse(input: string, options?: ParserOptions): RootNode {
index 4d06a776b7af98e0500fb20f70fc3651971ee952..38e5e8b9d517382e806a3c719c2554b4f7a927bd 100644 (file)
@@ -5,16 +5,11 @@ import {
   NodeTypes,
   isBuiltInType
 } from '@vue/compiler-core'
-import { makeMap, isVoidTag, isHTMLTag, isSVGTag } from '@vue/shared'
+import { isVoidTag, isHTMLTag, isSVGTag } from '@vue/shared'
 import { TRANSITION, TRANSITION_GROUP } from './runtimeHelpers'
 import { decodeHtml } from './decodeHtml'
 import { decodeHtmlBrowser } from './decodeHtmlBrowser'
 
-const isRawTextContainer = /*#__PURE__*/ makeMap(
-  'style,iframe,script,noscript',
-  true
-)
-
 export const enum DOMNamespaces {
   HTML = 0 /* Namespaces.HTML */,
   SVG,
@@ -38,7 +33,6 @@ export const parserOptions: ParserOptions = {
   // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
   getNamespace(tag: string, parent: ElementNode | undefined): DOMNamespaces {
     let ns = parent ? parent.ns : DOMNamespaces.HTML
-
     if (parent && ns === DOMNamespaces.MATH_ML) {
       if (parent.tag === 'annotation-xml') {
         if (tag === 'svg') {
@@ -90,7 +84,7 @@ export const parserOptions: ParserOptions = {
       if (tag === 'textarea' || tag === 'title') {
         return TextModes.RCDATA
       }
-      if (isRawTextContainer(tag)) {
+      if (tag === 'style' || tag === 'script') {
         return TextModes.RAWTEXT
       }
     }