1- import { insertBefore } from '../util/language-util.js' ;
2-
31/** @type {import('../types.d.ts').LanguageProto<'http'> } */
42export default {
53 id : 'http' ,
@@ -13,7 +11,64 @@ export default {
1311 return RegExp ( '(^(?:' + name + '):[ \t]*(?![ \t]))[^]+' , 'i' ) ;
1412 }
1513
16- const http = {
14+ // Create a mapping of Content-Type headers to language definitions
15+ const httpLanguages = {
16+ 'application/javascript' : 'javascript' ,
17+ 'application/json' : getOptionalLanguage ( 'json' ) || 'javascript' ,
18+ 'application/xml' : 'xml' ,
19+ 'text/xml' : 'xml' ,
20+ 'text/html' : 'html' ,
21+ 'text/css' : 'css' ,
22+ 'text/plain' : 'plain' ,
23+ } ;
24+
25+ // Declare which types can also be suffixes
26+ const suffixTypes = {
27+ 'application/json' : true ,
28+ 'application/xml' : true ,
29+ } ;
30+
31+ /**
32+ * Returns a pattern for the given content type which matches it and any type which has it as a suffix.
33+ *
34+ * @param {string } contentType
35+ * @returns {string }
36+ */
37+ function getSuffixPattern ( contentType ) {
38+ const suffix = contentType . replace ( / ^ [ a - z ] + \/ / , '' ) ;
39+ const suffixPattern = '\\w+/(?:[\\w.-]+\\+)+' + suffix + '(?![+\\w.-])' ;
40+ return '(?:' + contentType + '|' + suffixPattern + ')' ;
41+ }
42+
43+ // Insert each content type parser that has its associated language
44+ // currently loaded.
45+
46+ const options = /** @type {import('../types.d.ts').GrammarTokens } */ ( { } ) ;
47+ for ( const key in httpLanguages ) {
48+ const contentType = key ;
49+
50+ const pattern = suffixTypes [ contentType ] ? getSuffixPattern ( contentType ) : contentType ;
51+ options [ contentType . replace ( / \/ / g, '-' ) ] = {
52+ pattern : RegExp (
53+ '(' +
54+ / c o n t e n t - t y p e : \s * / . source +
55+ pattern +
56+ / (?: (?: \r \n ? | \n ) [ \w - ] .* ) * (?: \r (?: \n | (? ! \n ) ) | \n ) / . source +
57+ ')' +
58+ // This is a little interesting:
59+ // The HTTP format spec required 1 empty line before the body to make everything unambiguous.
60+ // However, when writing code by hand (e.g. to display on a website) people can forget about this,
61+ // so we want to be liberal here. We will allow the empty line to be omitted if the first line of
62+ // the body does not start with a [\w-] character (as headers do).
63+ / [ ^ \t \w - ] [ \s \S ] * / . source ,
64+ 'i'
65+ ) ,
66+ lookbehind : true ,
67+ inside : httpLanguages [ contentType ] ,
68+ } ;
69+ }
70+
71+ return {
1772 'request-line' : {
1873 pattern :
1974 / ^ (?: C O N N E C T | D E L E T E | G E T | H E A D | O P T I O N S | P A T C H | P O S T | P R I | P U T | S E A R C H | T R A C E ) \s (?: h t t p s ? : \/ \/ | \/ ) \S * \s H T T P \/ [ \d . ] + / m,
@@ -94,66 +149,9 @@ export default {
94149 'punctuation' : / ^ : / ,
95150 } ,
96151 } ,
152+ $insertBefore : {
153+ 'header' : options ,
154+ } ,
97155 } ;
98-
99- // Create a mapping of Content-Type headers to language definitions
100- const httpLanguages = {
101- 'application/javascript' : 'javascript' ,
102- 'application/json' : getOptionalLanguage ( 'json' ) || 'javascript' ,
103- 'application/xml' : 'xml' ,
104- 'text/xml' : 'xml' ,
105- 'text/html' : 'html' ,
106- 'text/css' : 'css' ,
107- 'text/plain' : 'plain' ,
108- } ;
109-
110- // Declare which types can also be suffixes
111- const suffixTypes = {
112- 'application/json' : true ,
113- 'application/xml' : true ,
114- } ;
115-
116- /**
117- * Returns a pattern for the given content type which matches it and any type which has it as a suffix.
118- *
119- * @param {string } contentType
120- * @returns {string }
121- */
122- function getSuffixPattern ( contentType ) {
123- const suffix = contentType . replace ( / ^ [ a - z ] + \/ / , '' ) ;
124- const suffixPattern = '\\w+/(?:[\\w.-]+\\+)+' + suffix + '(?![+\\w.-])' ;
125- return '(?:' + contentType + '|' + suffixPattern + ')' ;
126- }
127-
128- // Insert each content type parser that has its associated language
129- // currently loaded.
130- /** @type {import('../types.d.ts').Grammar } */
131- const options = { } ;
132- for ( const key in httpLanguages ) {
133- const contentType = key ;
134-
135- const pattern = suffixTypes [ contentType ] ? getSuffixPattern ( contentType ) : contentType ;
136- options [ contentType . replace ( / \/ / g, '-' ) ] = {
137- pattern : RegExp (
138- '(' +
139- / c o n t e n t - t y p e : \s * / . source +
140- pattern +
141- / (?: (?: \r \n ? | \n ) [ \w - ] .* ) * (?: \r (?: \n | (? ! \n ) ) | \n ) / . source +
142- ')' +
143- // This is a little interesting:
144- // The HTTP format spec required 1 empty line before the body to make everything unambiguous.
145- // However, when writing code by hand (e.g. to display on a website) people can forget about this,
146- // so we want to be liberal here. We will allow the empty line to be omitted if the first line of
147- // the body does not start with a [\w-] character (as headers do).
148- / [ ^ \t \w - ] [ \s \S ] * / . source ,
149- 'i'
150- ) ,
151- lookbehind : true ,
152- inside : httpLanguages [ contentType ] ,
153- } ;
154- }
155- insertBefore ( http , 'header' , options ) ;
156-
157- return http ;
158156 } ,
159157} ;
0 commit comments