qml.js (5477B)
1 /* 2 Language: QML 3 Requires: javascript.js, xml.js 4 Author: John Foster <jfoster@esri.com> 5 Description: Syntax highlighting for the Qt Quick QML scripting language, based mostly off 6 the JavaScript parser. 7 Website: https://doc.qt.io/qt-5/qmlapplications.html 8 Category: scripting 9 */ 10 11 function qml(hljs) { 12 var KEYWORDS = { 13 keyword: 14 'in of on if for while finally var new function do return void else break catch ' + 15 'instanceof with throw case default try this switch continue typeof delete ' + 16 'let yield const export super debugger as async await import', 17 literal: 18 'true false null undefined NaN Infinity', 19 built_in: 20 'eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent ' + 21 'encodeURI encodeURIComponent escape unescape Object Function Boolean Error ' + 22 'EvalError InternalError RangeError ReferenceError StopIteration SyntaxError ' + 23 'TypeError URIError Number Math Date String RegExp Array Float32Array ' + 24 'Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array ' + 25 'Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require ' + 26 'module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect ' + 27 'Behavior bool color coordinate date double enumeration font geocircle georectangle ' + 28 'geoshape int list matrix4x4 parent point quaternion real rect ' + 29 'size string url variant vector2d vector3d vector4d ' + 30 'Promise' 31 }; 32 33 var QML_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9\\._]*'; 34 35 // Isolate property statements. Ends at a :, =, ;, ,, a comment or end of line. 36 // Use property class. 37 var PROPERTY = { 38 className: 'keyword', 39 begin: '\\bproperty\\b', 40 starts: { 41 className: 'string', 42 end: '(:|=|;|,|//|/\\*|$)', 43 returnEnd: true 44 } 45 }; 46 47 // Isolate signal statements. Ends at a ) a comment or end of line. 48 // Use property class. 49 var SIGNAL = { 50 className: 'keyword', 51 begin: '\\bsignal\\b', 52 starts: { 53 className: 'string', 54 end: '(\\(|:|=|;|,|//|/\\*|$)', 55 returnEnd: true 56 } 57 }; 58 59 // id: is special in QML. When we see id: we want to mark the id: as attribute and 60 // emphasize the token following. 61 var ID_ID = { 62 className: 'attribute', 63 begin: '\\bid\\s*:', 64 starts: { 65 className: 'string', 66 end: QML_IDENT_RE, 67 returnEnd: false 68 } 69 }; 70 71 // Find QML object attribute. An attribute is a QML identifier followed by :. 72 // Unfortunately it's hard to know where it ends, as it may contain scalars, 73 // objects, object definitions, or javascript. The true end is either when the parent 74 // ends or the next attribute is detected. 75 var QML_ATTRIBUTE = { 76 begin: QML_IDENT_RE + '\\s*:', 77 returnBegin: true, 78 contains: [ 79 { 80 className: 'attribute', 81 begin: QML_IDENT_RE, 82 end: '\\s*:', 83 excludeEnd: true, 84 relevance: 0 85 } 86 ], 87 relevance: 0 88 }; 89 90 // Find QML object. A QML object is a QML identifier followed by { and ends at the matching }. 91 // All we really care about is finding IDENT followed by { and just mark up the IDENT and ignore the {. 92 var QML_OBJECT = { 93 begin: QML_IDENT_RE + '\\s*{', end: '{', 94 returnBegin: true, 95 relevance: 0, 96 contains: [ 97 hljs.inherit(hljs.TITLE_MODE, {begin: QML_IDENT_RE}) 98 ] 99 }; 100 101 return { 102 name: 'QML', 103 aliases: ['qt'], 104 case_insensitive: false, 105 keywords: KEYWORDS, 106 contains: [ 107 { 108 className: 'meta', 109 begin: /^\s*['"]use (strict|asm)['"]/ 110 }, 111 hljs.APOS_STRING_MODE, 112 hljs.QUOTE_STRING_MODE, 113 { // template string 114 className: 'string', 115 begin: '`', end: '`', 116 contains: [ 117 hljs.BACKSLASH_ESCAPE, 118 { 119 className: 'subst', 120 begin: '\\$\\{', end: '\\}' 121 } 122 ] 123 }, 124 hljs.C_LINE_COMMENT_MODE, 125 hljs.C_BLOCK_COMMENT_MODE, 126 { 127 className: 'number', 128 variants: [ 129 { begin: '\\b(0[bB][01]+)' }, 130 { begin: '\\b(0[oO][0-7]+)' }, 131 { begin: hljs.C_NUMBER_RE } 132 ], 133 relevance: 0 134 }, 135 { // "value" container 136 begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*', 137 keywords: 'return throw case', 138 contains: [ 139 hljs.C_LINE_COMMENT_MODE, 140 hljs.C_BLOCK_COMMENT_MODE, 141 hljs.REGEXP_MODE, 142 { // E4X / JSX 143 begin: /</, end: />\s*[);\]]/, 144 relevance: 0, 145 subLanguage: 'xml' 146 } 147 ], 148 relevance: 0 149 }, 150 SIGNAL, 151 PROPERTY, 152 { 153 className: 'function', 154 beginKeywords: 'function', end: /\{/, excludeEnd: true, 155 contains: [ 156 hljs.inherit(hljs.TITLE_MODE, {begin: /[A-Za-z$_][0-9A-Za-z$_]*/}), 157 { 158 className: 'params', 159 begin: /\(/, end: /\)/, 160 excludeBegin: true, 161 excludeEnd: true, 162 contains: [ 163 hljs.C_LINE_COMMENT_MODE, 164 hljs.C_BLOCK_COMMENT_MODE 165 ] 166 } 167 ], 168 illegal: /\[|%/ 169 }, 170 { 171 begin: '\\.' + hljs.IDENT_RE, relevance: 0 // hack: prevents detection of keywords after dots 172 }, 173 ID_ID, 174 QML_ATTRIBUTE, 175 QML_OBJECT 176 ], 177 illegal: /#/ 178 }; 179 } 180 181 module.exports = qml;