@@ -24,20 +24,188 @@ Prism.languages.graphql = {
2424 alias : 'function'
2525 } ,
2626 'attr-name' : {
27- pattern : / \b [ a - z _ ] \w * (? = \s * (?: \( (?: [ ^ ( ) " ] | " (?: \\ .| [ ^ \\ " \r \n ] ) * " ) * \) ) ? : ) / i,
27+ pattern : / [ a - z _ ] \w * (? = \s * (?: \( (?: [ ^ ( ) " ] | " (?: \\ .| [ ^ \\ " \r \n ] ) * " ) * \) ) ? : ) / i,
2828 greedy : true
2929 } ,
30+ 'atom-input' : {
31+ pattern : / [ A - Z ] \w * I n p u t (? = ! ? .* $ ) / m,
32+ alias : 'class-name'
33+ } ,
34+ 'scalar' : / \b (?: B o o l e a n | F l o a t | I D | I n t | S t r i n g ) \b / ,
35+ 'constant' : / \b [ A - Z ] [ A - Z _ \d ] * \b / ,
3036 'class-name' : {
31- pattern : / ( \b (?: e n u m | i m p l e m e n t s | i n t e r f a c e | o n | s c a l a r | t y p e | u n i o n ) \s + | & \s * ) [ a - z A - Z _ ] \w * / ,
37+ pattern : / ( \b (?: e n u m | i m p l e m e n t s | i n t e r f a c e | o n | s c a l a r | t y p e | u n i o n ) \s + | & \s * | : \s * | \[ ) [ A - Z _ ] \w * / ,
3238 lookbehind : true
3339 } ,
3440 'fragment' : {
3541 pattern : / ( \b f r a g m e n t \s + | \. { 3 } \s * (? ! o n \b ) ) [ a - z A - Z _ ] \w * / ,
3642 lookbehind : true ,
3743 alias : 'function'
3844 } ,
45+ 'definition-mutation' : {
46+ pattern : / ( \b m u t a t i o n \s + | \. { 3 } \s * ) [ a - z A - Z _ ] \w * / ,
47+ lookbehind : true ,
48+ alias : 'function'
49+ } ,
50+ 'definition-query' : {
51+ pattern : / ( \b q u e r y \s + | \. { 3 } \s * ) [ a - z A - Z _ ] \w * / ,
52+ lookbehind : true ,
53+ alias : 'function'
54+ } ,
3955 'keyword' : / \b (?: d i r e c t i v e | e n u m | e x t e n d | f r a g m e n t | i m p l e m e n t s | i n p u t | i n t e r f a c e | m u t a t i o n | o n | q u e r y | r e p e a t a b l e | s c a l a r | s c h e m a | s u b s c r i p t i o n | t y p e | u n i o n ) \b / ,
4056 'operator' : / [ ! = | & ] | \. { 3 } / ,
57+ 'property-query' : / \w + (? = \s * \( ) / ,
58+ 'object' : / \w + (? = \s * { ) / ,
4159 'punctuation' : / [ ! ( ) { } \[ \] : = , ] / ,
42- 'constant ' : / \b (? ! I D \b ) [ A - Z ] [ A - Z _ \d ] * \b /
60+ 'property ' : / \w + /
4361} ;
62+
63+ Prism . hooks . add ( 'after-tokenize' , function afterTokenizeGraphql ( env ) {
64+ if ( env . language !== 'graphql' ) {
65+ return ;
66+ }
67+
68+ /**
69+ * get the graphql token stream that we want to customize
70+ *
71+ * @typedef {InstanceType<import("./prism-core")["Token"]> } Token
72+ * @type {Token[] }
73+ */
74+ var validTokens = env . tokens . filter ( function ( token ) {
75+ return typeof token !== 'string' && token . type !== 'comment' && token . type !== 'scalar' ;
76+ } ) ;
77+
78+ var currentIndex = 0 ;
79+
80+ /**
81+ * Returns whether the token relative to the current index has the given type.
82+ *
83+ * @param {number } offset
84+ * @returns {Token | undefined }
85+ */
86+ function getToken ( offset ) {
87+ return validTokens [ currentIndex + offset ] ;
88+ }
89+
90+ /**
91+ * Returns whether the token relative to the current index has the given type.
92+ *
93+ * @param {readonly string[] } types
94+ * @param {number } [offset=0]
95+ * @returns {boolean }
96+ */
97+ function isTokenType ( types , offset ) {
98+ offset = offset || 0 ;
99+ for ( var i = 0 ; i < types . length ; i ++ ) {
100+ var token = getToken ( i + offset ) ;
101+ if ( ! token || token . type !== types [ i ] ) {
102+ return false ;
103+ }
104+ }
105+ return true ;
106+ }
107+
108+ /**
109+ * Returns the index of the closing bracket to an opening bracket.
110+ *
111+ * It is assumed that `token[currentIndex - 1]` is an opening bracket.
112+ *
113+ * If no closing bracket could be found, `-1` will be returned.
114+ *
115+ * @param {RegExp } open
116+ * @param {RegExp } close
117+ * @returns {number }
118+ */
119+ function findClosingBracket ( open , close ) {
120+ var stackHeight = 1 ;
121+
122+ for ( var i = currentIndex ; i < validTokens . length ; i ++ ) {
123+ var token = validTokens [ i ] ;
124+ var content = token . content ;
125+
126+ if ( token . type === 'punctuation' && typeof content === 'string' ) {
127+ if ( open . test ( content ) ) {
128+ stackHeight ++ ;
129+ } else if ( close . test ( content ) ) {
130+ stackHeight -- ;
131+
132+ if ( stackHeight === 0 ) {
133+ return i ;
134+ }
135+ }
136+ }
137+ }
138+
139+ return - 1 ;
140+ }
141+
142+ /**
143+ * Adds an alias to the given token.
144+ *
145+ * @param {Token } token
146+ * @param {string } alias
147+ * @returns {void }
148+ */
149+ function addAlias ( token , alias ) {
150+ var aliases = token . alias ;
151+ if ( ! aliases ) {
152+ token . alias = aliases = [ ] ;
153+ } else if ( ! Array . isArray ( aliases ) ) {
154+ token . alias = aliases = [ aliases ] ;
155+ }
156+ aliases . push ( alias ) ;
157+ }
158+
159+ for ( ; currentIndex < validTokens . length ; ) {
160+ var startToken = validTokens [ currentIndex ++ ] ;
161+
162+ // add special aliases for mutation tokens
163+ if ( startToken . type === 'keyword' && startToken . content === 'mutation' ) {
164+ // any array of the names of all input variables (if any)
165+ var inputVariables = [ ] ;
166+
167+ if ( isTokenType ( [ 'definition-mutation' , 'punctuation' ] ) && getToken ( 1 ) . content === '(' ) {
168+ // definition
169+
170+ currentIndex += 2 ; // skip 'definition-mutation' and 'punctuation'
171+
172+ var definitionEnd = findClosingBracket ( / ^ \( $ / , / ^ \) $ / ) ;
173+ if ( definitionEnd === - 1 ) {
174+ continue ;
175+ }
176+
177+ // find all input variables
178+ for ( ; currentIndex < definitionEnd ; currentIndex ++ ) {
179+ var t = getToken ( 0 ) ;
180+ if ( t . type === 'variable' ) {
181+ addAlias ( t , 'variable-input' ) ;
182+ inputVariables . push ( t . content ) ;
183+ }
184+ }
185+
186+ currentIndex = definitionEnd + 1 ;
187+ }
188+
189+ if ( isTokenType ( [ 'punctuation' , 'property-query' ] ) && getToken ( 0 ) . content === '{' ) {
190+ currentIndex ++ ; // skip opening bracket
191+
192+ addAlias ( getToken ( 0 ) , 'property-mutation' ) ;
193+
194+ if ( inputVariables . length > 0 ) {
195+ var mutationEnd = findClosingBracket ( / ^ { $ / , / ^ } $ / ) ;
196+ if ( mutationEnd === - 1 ) {
197+ continue ;
198+ }
199+
200+ // give references to input variables a special alias
201+ for ( var i = currentIndex ; i < mutationEnd ; i ++ ) {
202+ var varToken = validTokens [ i ] ;
203+ if ( varToken . type === 'variable' && inputVariables . indexOf ( varToken . content ) >= 0 ) {
204+ addAlias ( varToken , 'variable-input' ) ;
205+ }
206+ }
207+ }
208+ }
209+ }
210+ }
211+ } ) ;
0 commit comments