|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- 'use strict'
-
- var asciiAlpha = require('../character/ascii-alpha.js')
- var asciiAlphanumeric = require('../character/ascii-alphanumeric.js')
- var markdownLineEnding = require('../character/markdown-line-ending.js')
- var markdownLineEndingOrSpace = require('../character/markdown-line-ending-or-space.js')
- var markdownSpace = require('../character/markdown-space.js')
- var fromCharCode = require('../constant/from-char-code.js')
- var htmlBlockNames = require('../constant/html-block-names.js')
- var htmlRawNames = require('../constant/html-raw-names.js')
- var partialBlankLine = require('./partial-blank-line.js')
-
- var htmlFlow = {
- name: 'htmlFlow',
- tokenize: tokenizeHtmlFlow,
- resolveTo: resolveToHtmlFlow,
- concrete: true
- }
- var nextBlankConstruct = {
- tokenize: tokenizeNextBlank,
- partial: true
- }
-
- function resolveToHtmlFlow(events) {
- var index = events.length
-
- while (index--) {
- if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') {
- break
- }
- }
-
- if (index > 1 && events[index - 2][1].type === 'linePrefix') {
- // Add the prefix start to the HTML token.
- events[index][1].start = events[index - 2][1].start // Add the prefix start to the HTML line token.
-
- events[index + 1][1].start = events[index - 2][1].start // Remove the line prefix.
-
- events.splice(index - 2, 2)
- }
-
- return events
- }
-
- function tokenizeHtmlFlow(effects, ok, nok) {
- var self = this
- var kind
- var startTag
- var buffer
- var index
- var marker
- return start
-
- function start(code) {
- effects.enter('htmlFlow')
- effects.enter('htmlFlowData')
- effects.consume(code)
- return open
- }
-
- function open(code) {
- if (code === 33) {
- effects.consume(code)
- return declarationStart
- }
-
- if (code === 47) {
- effects.consume(code)
- return tagCloseStart
- }
-
- if (code === 63) {
- effects.consume(code)
- kind = 3 // While we’re in an instruction instead of a declaration, we’re on a `?`
- // right now, so we do need to search for `>`, similar to declarations.
-
- return self.interrupt ? ok : continuationDeclarationInside
- }
-
- if (asciiAlpha(code)) {
- effects.consume(code)
- buffer = fromCharCode(code)
- startTag = true
- return tagName
- }
-
- return nok(code)
- }
-
- function declarationStart(code) {
- if (code === 45) {
- effects.consume(code)
- kind = 2
- return commentOpenInside
- }
-
- if (code === 91) {
- effects.consume(code)
- kind = 5
- buffer = 'CDATA['
- index = 0
- return cdataOpenInside
- }
-
- if (asciiAlpha(code)) {
- effects.consume(code)
- kind = 4
- return self.interrupt ? ok : continuationDeclarationInside
- }
-
- return nok(code)
- }
-
- function commentOpenInside(code) {
- if (code === 45) {
- effects.consume(code)
- return self.interrupt ? ok : continuationDeclarationInside
- }
-
- return nok(code)
- }
-
- function cdataOpenInside(code) {
- if (code === buffer.charCodeAt(index++)) {
- effects.consume(code)
- return index === buffer.length
- ? self.interrupt
- ? ok
- : continuation
- : cdataOpenInside
- }
-
- return nok(code)
- }
-
- function tagCloseStart(code) {
- if (asciiAlpha(code)) {
- effects.consume(code)
- buffer = fromCharCode(code)
- return tagName
- }
-
- return nok(code)
- }
-
- function tagName(code) {
- if (
- code === null ||
- code === 47 ||
- code === 62 ||
- markdownLineEndingOrSpace(code)
- ) {
- if (
- code !== 47 &&
- startTag &&
- htmlRawNames.indexOf(buffer.toLowerCase()) > -1
- ) {
- kind = 1
- return self.interrupt ? ok(code) : continuation(code)
- }
-
- if (htmlBlockNames.indexOf(buffer.toLowerCase()) > -1) {
- kind = 6
-
- if (code === 47) {
- effects.consume(code)
- return basicSelfClosing
- }
-
- return self.interrupt ? ok(code) : continuation(code)
- }
-
- kind = 7 // Do not support complete HTML when interrupting.
-
- return self.interrupt
- ? nok(code)
- : startTag
- ? completeAttributeNameBefore(code)
- : completeClosingTagAfter(code)
- }
-
- if (code === 45 || asciiAlphanumeric(code)) {
- effects.consume(code)
- buffer += fromCharCode(code)
- return tagName
- }
-
- return nok(code)
- }
-
- function basicSelfClosing(code) {
- if (code === 62) {
- effects.consume(code)
- return self.interrupt ? ok : continuation
- }
-
- return nok(code)
- }
-
- function completeClosingTagAfter(code) {
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeClosingTagAfter
- }
-
- return completeEnd(code)
- }
-
- function completeAttributeNameBefore(code) {
- if (code === 47) {
- effects.consume(code)
- return completeEnd
- }
-
- if (code === 58 || code === 95 || asciiAlpha(code)) {
- effects.consume(code)
- return completeAttributeName
- }
-
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeAttributeNameBefore
- }
-
- return completeEnd(code)
- }
-
- function completeAttributeName(code) {
- if (
- code === 45 ||
- code === 46 ||
- code === 58 ||
- code === 95 ||
- asciiAlphanumeric(code)
- ) {
- effects.consume(code)
- return completeAttributeName
- }
-
- return completeAttributeNameAfter(code)
- }
-
- function completeAttributeNameAfter(code) {
- if (code === 61) {
- effects.consume(code)
- return completeAttributeValueBefore
- }
-
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeAttributeNameAfter
- }
-
- return completeAttributeNameBefore(code)
- }
-
- function completeAttributeValueBefore(code) {
- if (
- code === null ||
- code === 60 ||
- code === 61 ||
- code === 62 ||
- code === 96
- ) {
- return nok(code)
- }
-
- if (code === 34 || code === 39) {
- effects.consume(code)
- marker = code
- return completeAttributeValueQuoted
- }
-
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeAttributeValueBefore
- }
-
- marker = undefined
- return completeAttributeValueUnquoted(code)
- }
-
- function completeAttributeValueQuoted(code) {
- if (code === marker) {
- effects.consume(code)
- return completeAttributeValueQuotedAfter
- }
-
- if (code === null || markdownLineEnding(code)) {
- return nok(code)
- }
-
- effects.consume(code)
- return completeAttributeValueQuoted
- }
-
- function completeAttributeValueUnquoted(code) {
- if (
- code === null ||
- code === 34 ||
- code === 39 ||
- code === 60 ||
- code === 61 ||
- code === 62 ||
- code === 96 ||
- markdownLineEndingOrSpace(code)
- ) {
- return completeAttributeNameAfter(code)
- }
-
- effects.consume(code)
- return completeAttributeValueUnquoted
- }
-
- function completeAttributeValueQuotedAfter(code) {
- if (code === 47 || code === 62 || markdownSpace(code)) {
- return completeAttributeNameBefore(code)
- }
-
- return nok(code)
- }
-
- function completeEnd(code) {
- if (code === 62) {
- effects.consume(code)
- return completeAfter
- }
-
- return nok(code)
- }
-
- function completeAfter(code) {
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeAfter
- }
-
- return code === null || markdownLineEnding(code)
- ? continuation(code)
- : nok(code)
- }
-
- function continuation(code) {
- if (code === 45 && kind === 2) {
- effects.consume(code)
- return continuationCommentInside
- }
-
- if (code === 60 && kind === 1) {
- effects.consume(code)
- return continuationRawTagOpen
- }
-
- if (code === 62 && kind === 4) {
- effects.consume(code)
- return continuationClose
- }
-
- if (code === 63 && kind === 3) {
- effects.consume(code)
- return continuationDeclarationInside
- }
-
- if (code === 93 && kind === 5) {
- effects.consume(code)
- return continuationCharacterDataInside
- }
-
- if (markdownLineEnding(code) && (kind === 6 || kind === 7)) {
- return effects.check(
- nextBlankConstruct,
- continuationClose,
- continuationAtLineEnding
- )(code)
- }
-
- if (code === null || markdownLineEnding(code)) {
- return continuationAtLineEnding(code)
- }
-
- effects.consume(code)
- return continuation
- }
-
- function continuationAtLineEnding(code) {
- effects.exit('htmlFlowData')
- return htmlContinueStart(code)
- }
-
- function htmlContinueStart(code) {
- if (code === null) {
- return done(code)
- }
-
- if (markdownLineEnding(code)) {
- effects.enter('lineEnding')
- effects.consume(code)
- effects.exit('lineEnding')
- return htmlContinueStart
- }
-
- effects.enter('htmlFlowData')
- return continuation(code)
- }
-
- function continuationCommentInside(code) {
- if (code === 45) {
- effects.consume(code)
- return continuationDeclarationInside
- }
-
- return continuation(code)
- }
-
- function continuationRawTagOpen(code) {
- if (code === 47) {
- effects.consume(code)
- buffer = ''
- return continuationRawEndTag
- }
-
- return continuation(code)
- }
-
- function continuationRawEndTag(code) {
- if (code === 62 && htmlRawNames.indexOf(buffer.toLowerCase()) > -1) {
- effects.consume(code)
- return continuationClose
- }
-
- if (asciiAlpha(code) && buffer.length < 8) {
- effects.consume(code)
- buffer += fromCharCode(code)
- return continuationRawEndTag
- }
-
- return continuation(code)
- }
-
- function continuationCharacterDataInside(code) {
- if (code === 93) {
- effects.consume(code)
- return continuationDeclarationInside
- }
-
- return continuation(code)
- }
-
- function continuationDeclarationInside(code) {
- if (code === 62) {
- effects.consume(code)
- return continuationClose
- }
-
- return continuation(code)
- }
-
- function continuationClose(code) {
- if (code === null || markdownLineEnding(code)) {
- effects.exit('htmlFlowData')
- return done(code)
- }
-
- effects.consume(code)
- return continuationClose
- }
-
- function done(code) {
- effects.exit('htmlFlow')
- return ok(code)
- }
- }
-
- function tokenizeNextBlank(effects, ok, nok) {
- return start
-
- function start(code) {
- effects.exit('htmlFlowData')
- effects.enter('lineEndingBlank')
- effects.consume(code)
- effects.exit('lineEndingBlank')
- return effects.attempt(partialBlankLine, ok, nok)
- }
- }
-
- module.exports = htmlFlow
|