li
Version:
Parse the Links header format and return a javascript object.
92 lines (72 loc) • 2.71 kB
JavaScript
(function (name, definition, context) {
//try CommonJS, then AMD (require.js), then use global.
if (typeof module != 'undefined' && module.exports) module.exports = definition();
else if (typeof context['define'] == 'function' && context['define']['amd']) define(definition);
else context[name] = definition();
})('li', function () {
// compile regular expressions ahead of time for efficiency
var relsRegExp = /^;\s*([^"=]+)=(?:"([^"]+)"|([^";,]+)(?:[;,]|$))/;
var sourceRegExp = /^<([^>]*)>/;
var delimiterRegExp = /^\s*,\s*/;
return {
parse: function (linksHeader, options) {
var match;
var source;
var rels;
var extended = options && options.extended || false;
var links = [];
while (linksHeader) {
linksHeader = linksHeader.trim();
// Parse `<link>`
source = sourceRegExp.exec(linksHeader);
if (!source) break;
var current = {
link: source[1]
};
// Move cursor
linksHeader = linksHeader.slice(source[0].length);
// Parse `; attr=relation` and `; attr="relation"`
var nextDelimiter = linksHeader.match(delimiterRegExp);
while(linksHeader && (!nextDelimiter || nextDelimiter.index > 0)) {
match = relsRegExp.exec(linksHeader);
if (!match) break;
// Move cursor
linksHeader = linksHeader.slice(match[0].length);
nextDelimiter = linksHeader.match(delimiterRegExp);
if (match[1] === 'rel' || match[1] === 'rev') {
// Add either quoted rel or unquoted rel
rels = (match[2] || match[3]).split(/\s+/);
current[match[1]] = rels;
} else {
current[match[1]] = match[2] || match[3];
}
}
links.push(current);
// Move cursor
linksHeader = linksHeader.replace(delimiterRegExp, '');
}
if (!extended) {
return links.reduce(function(result, currentLink) {
if (currentLink.rel) {
currentLink.rel.forEach(function(rel) {
result[rel] = currentLink.link;
});
}
return result;
}, {});
}
return links;
},
stringify: function (params) {
var grouped = Object.keys(params).reduce(function(grouped, key) {
grouped[params[key]] = grouped[params[key]] || [];
grouped[params[key]].push(key);
return grouped;
}, {});
var entries = Object.keys(grouped).reduce(function(result, link) {
return result.concat('<' + link + '>; rel="' + grouped[link].join(' ') + '"');
}, []);
return entries.join(', ');
}
};
}, this);