private scanAttrs()

in packages/miniapp-runtime/src/dom-external/inner-html/scaner.ts [248:335]


  private scanAttrs() {
    const { html, position, tokens } = this;
    let cursor = position.index;
    let quote: string | null = null; // null, single-, or double-quote
    let wordBegin = cursor; // index of word start
    const words: string[] = []; // "key", "key=value", "key='value'", etc
    const len = html.length;
    while (cursor < len) {
      const char = html.charAt(cursor);
      if (quote) {
        const isQuoteEnd = char === quote;
        if (isQuoteEnd) {
          quote = null;
        }
        cursor++;
        continue;
      }

      const isTagEnd = char === '/' || char === '>';
      if (isTagEnd) {
        if (cursor !== wordBegin) {
          words.push(html.slice(wordBegin, cursor));
        }
        break;
      }

      if (isWordEnd(cursor, wordBegin, html)) {
        if (cursor !== wordBegin) {
          words.push(html.slice(wordBegin, cursor));
        }
        wordBegin = cursor + 1;
        cursor++;
        continue;
      }

      const isQuoteStart = char === '\'' || char === '"';
      if (isQuoteStart) {
        quote = char;
        cursor++;
        continue;
      }

      cursor++;
    }

    jumpPosition(position, html, cursor);

    const wLen = words.length;
    const type = 'attribute';
    for (let i = 0; i < wLen; i++) {
      const word = words[i];
      const isNotPair = word.includes('=');
      if (isNotPair) {
        const secondWord = words[i + 1];
        if (secondWord && secondWord.startsWith('=')) {
          if (secondWord.length > 1) {
            const newWord = word + secondWord;
            tokens.push({ type, content: newWord });
            i += 1;
            continue;
          }
          const thirdWord = words[i + 2];
          i += 1;
          if (thirdWord) {
            const newWord = `${word}=${thirdWord}`;
            tokens.push({ type, content: newWord });
            i += 1;
            continue;
          }
        }
      }
      if (word.endsWith('=')) {
        const secondWord = words[i + 1];
        if (secondWord && !secondWord.includes('=')) {
          const newWord = word + secondWord;
          tokens.push({ type, content: newWord });
          i += 1;
          continue;
        }

        const newWord = word.slice(0, -1);
        tokens.push({ type, content: newWord });
        continue;
      }

      tokens.push({ type, content: word });
    }
  }