|
|
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;
|
|
|
});
|