jsx-like-tokenizer.js 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. "use strict";
  2. const htmlparser = require("htmlparser2");
  3. const jsTokens = require("js-tokens");
  4. const OPEN_BRACE = "{".charCodeAt(0);
  5. module.exports = class JsxLikeTokenizer extends htmlparser.Tokenizer {
  6. stateBeforeAttributeValue(c) {
  7. if (c === OPEN_BRACE) {
  8. const startIndex = this.index;
  9. const endIndex = getIndexOfExpressionEnd(this.buffer, startIndex + 1);
  10. if (endIndex != null) {
  11. this.sectionStart = startIndex;
  12. this.index = endIndex + 1;
  13. this.cbs.onattribdata(this.sectionStart, this.index);
  14. this.sectionStart = -1;
  15. this.cbs.onattribend(1 /* QuoteType.Unquoted */, this.index);
  16. this.state = 8 /* BeforeAttributeName */;
  17. this.stateBeforeAttributeName(this.buffer.charCodeAt(this.index));
  18. return;
  19. }
  20. }
  21. super.stateBeforeAttributeValue(c);
  22. }
  23. };
  24. function getIndexOfExpressionEnd(source, startIndex) {
  25. let index = startIndex;
  26. let braceStack = 0;
  27. for (const token of jsTokens(source.slice(startIndex))) {
  28. if (token.value === "}") {
  29. if (braceStack === 0) {
  30. return index;
  31. }
  32. braceStack--;
  33. } else if (token.value === "{") {
  34. braceStack++;
  35. }
  36. index += token.value.length;
  37. }
  38. return null;
  39. }