ContentType.js
205 lines
| 5.7 KiB
| application/javascript
|
JavascriptLexer
|
|
r0 | define([ "dojo/_base/declare", "dojo/_base/lang" ], function(declare, lang) { | |
| let cls = declare(null, { | |||
| type : null, | |||
| subtype : null, | |||
| parameters: null, | |||
| constructor: function(media,parameters) { | |||
| if (!media) | |||
| throw "A media must be specified"; | |||
| media = media.toString(); | |||
| let parts = media.match(/^([a-zA-Z-]+)\/([a-zA-Z\-+]+)$/); | |||
| if(!parts) | |||
| throw "An invalid media type supplied"; | |||
| this.type = parts[1]; | |||
| this.subtype = parts[2]; | |||
| this.parameters = parameters || {}; | |||
| }, | |||
| toString : function() { | |||
| let res = [this.type,'/',this.subtype]; | |||
| for(var p in this.parameters) { | |||
| res.push('; '); | |||
| res.push(p); | |||
| res.push('='); | |||
| res.push(this._escapeValue(this.parameters[p])); | |||
| } | |||
| return res.join(''); | |||
| }, | |||
| _escapeValue : function(value) { | |||
| if (value) { | |||
| value = value.toString(); | |||
| if(value.match(/[()<>@,:;\\".[\]]/)) | |||
| return '"' + value.replace(/[()<>@,:;\\".[\]]/g, function(x) { return "\\"+ x; } ) + '"'; | |||
| } | |||
| return value; | |||
| } | |||
| }); | |||
| let parseSpace = function(text,start) { | |||
| for(var i = start; i < text.length; i++) { | |||
| if(!text[i].match(/\s/)) | |||
| break; | |||
| } | |||
| return { | |||
| pos: i | |||
| }; | |||
| }; | |||
| let parseToken = function(text,start,required) { | |||
| let token = []; | |||
| for(var i=start; i< text.length; i++) { | |||
| let char = text[i]; | |||
| if (!char.match(/[\w-]/)) | |||
| break; | |||
| token.push(char); | |||
| } | |||
| if (required && token.length == 0) { | |||
| if (i == text.length) | |||
| throw new Error("Unexpected end of line"); | |||
| else | |||
| throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[i], pos: i}); | |||
| } | |||
| return { | |||
| value : token.join(''), | |||
| pos : i | |||
| }; | |||
| }; | |||
| let parseMedia = function(text,start) { | |||
| let type, subtype; | |||
| let t = parseToken(text,start,true); | |||
| type = t.value; | |||
| start = t.pos; | |||
| if (text[start] != '/') | |||
| throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[start], pos: start}); | |||
| start++; | |||
| t = parseToken(text,start,true); | |||
| subtype = t.value; | |||
| start = t.pos; | |||
| return { | |||
| value: { | |||
| type : type, | |||
| subtype: subtype | |||
| }, | |||
| pos : start | |||
| }; | |||
| }; | |||
| let parseLiteral = function(text,pos,required) { | |||
| let data = []; | |||
| let escape, stop; | |||
| for(var i=pos; (i < text.length) && !stop; i++) { | |||
| if (escape) { | |||
| data.push(text[i]); | |||
| escape = false; | |||
| } else { | |||
| switch(text[i]) { | |||
| case '"': | |||
| if (pos != i) | |||
| stop = true; | |||
| break; | |||
| case '\\': | |||
| escape = true; | |||
| break; | |||
| default: | |||
| if (pos == i) { | |||
| stop = true; | |||
| i--; | |||
| } else { | |||
| data.push(text[i]); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| if(required && data.length == 0) | |||
| new lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[i], pos: i}); | |||
| return { | |||
| value : data.join(''), | |||
| pos : i | |||
| }; | |||
| }; | |||
| let parseParam = function(text,pos) { | |||
| let t,name,value; | |||
| t = parseToken(text,pos,true); | |||
| name = t.value; | |||
| pos = t.pos; | |||
| t = parseSpace(text,pos); | |||
| pos = t.pos; | |||
| if (text[pos] != '=') | |||
| throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[pos], pos: pos}); | |||
| pos++; | |||
| t = parseSpace(text,pos); | |||
| pos = t.pos; | |||
| t = parseToken(text,pos,false); | |||
| if (t.pos != pos) { | |||
| value = t.value; | |||
| pos = t.pos; | |||
| } else { | |||
| t = parseLiteral(text,pos,false); | |||
| if (t.pos == pos) | |||
| throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[pos], pos: pos}); | |||
| pos = t.pos; | |||
| value = t.value; | |||
| } | |||
| return { | |||
| value : { | |||
| name : name, | |||
| value : value | |||
| }, | |||
| pos : pos | |||
| }; | |||
| }; | |||
| cls.parse = function(text) { | |||
| let t,pos = 0, media, params = {}; | |||
| t = parseMedia(text,pos); | |||
| media = t.value; | |||
| pos = t.pos; | |||
| while(pos < text.length) { | |||
| t = parseSpace(text,pos); | |||
| pos = t.pos; | |||
| if (pos < text.length) { | |||
| if(text[pos] == ';') { | |||
| pos ++; | |||
| t = parseSpace(text,pos); | |||
| pos = t.pos; | |||
| t = parseParam(text,pos); | |||
| params[t.value.name] = t.value.value; | |||
| pos = t.pos; | |||
| } else { | |||
| throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[pos], pos: pos}); | |||
| } | |||
| } | |||
| } | |||
| return new cls( media.type + '/' + media.subtype, params ); | |||
| }; | |||
| return cls; | |||
| }); |
