nodescore/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/charset.js

91 lines
1.9 KiB
JavaScript
Executable File

module.exports = preferredCharsets;
preferredCharsets.preferredCharsets = preferredCharsets;
function parseAcceptCharset(accept) {
return accept.split(',').map(function(e) {
return parseCharset(e.trim());
}).filter(function(e) {
return e;
});
}
function parseCharset(s) {
var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/);
if (!match) return null;
var charset = match[1];
var q = 1;
if (match[2]) {
var params = match[2].split(';')
for (var i = 0; i < params.length; i ++) {
var p = params[i].trim().split('=');
if (p[0] === 'q') {
q = parseFloat(p[1]);
break;
}
}
}
return {
charset: charset,
q: q
};
}
function getCharsetPriority(charset, accepted) {
return (accepted.map(function(a) {
return specify(charset, a);
}).filter(Boolean).sort(function (a, b) {
if(a.s == b.s) {
return a.q > b.q ? -1 : 1;
} else {
return a.s > b.s ? -1 : 1;
}
})[0] || {s: 0, q:0});
}
function specify(charset, spec) {
var s = 0;
if(spec.charset === charset){
s |= 1;
} else if (spec.charset !== '*' ) {
return null
}
return {
s: s,
q: spec.q,
}
}
function preferredCharsets(accept, provided) {
// RFC 2616 sec 14.2: no header = *
accept = parseAcceptCharset(accept === undefined ? '*' : accept || '');
if (provided) {
return provided.map(function(type) {
return [type, getCharsetPriority(type, accept)];
}).filter(function(pair) {
return pair[1].q > 0;
}).sort(function(a, b) {
var pa = a[1];
var pb = b[1];
if(pa.q == pb.q) {
return pa.s < pb.s ? 1 : -1;
} else {
return pa.q < pb.q ? 1 : -1;
}
}).map(function(pair) {
return pair[0];
});
} else {
return accept.sort(function (a, b) {
// revsort
return a.q < b.q ? 1 : -1;
}).filter(function(type) {
return type.q > 0;
}).map(function(type) {
return type.charset;
});
}
}