- this.xhtml['#'] += '<'+n['#name'];
- Object.keys(n['@']).forEach(function(name){
- this.xhtml['#'] += ' '+ name +'="'+ n['@'][name] + '"';
+ this.xhtml['#'] += '<' + n['#name'];
+ Object.keys(n['@']).forEach(function (name) {
+ this.xhtml['#'] += ' ' + name + '="' + n['@'][name] + '"';
}, this);
this.xhtml['#'] += '>';
- } else if ( this.stack.length === 0 &&
- (n['#name'] === 'rss' ||
- (n['#local'] === 'rdf' && _.nslookup([n['#uri']], 'rdf')) ||
- (n['#local'] === 'feed'&& _.nslookup([n['#uri']], 'atom')) ) ) {
- Object.keys(n['@']).forEach(function(name) {
+ } else if (this.stack.length === 0 &&
+ (n['#name'] === 'rss' ||
+ (n['#local'] === 'rdf' && _.nslookup([n['#uri']], 'rdf')) ||
+ (n['#local'] === 'feed' && _.nslookup([n['#uri']], 'atom')))) {
+ Object.keys(n['@']).forEach(function (name) {
var o = {};
if (name != 'version') {
o[name] = n['@'][name];
this.meta['@'].push(o);
}
}, this);
- switch(n['#local']) {
+ switch (n['#local']) {
case 'rss':
this.meta['#type'] = 'rss';
this.meta['#version'] = n['@']['version'];
@@ -224,11 +230,11 @@ FeedParser.prototype.handleOpenTag = function (node){
};
/** @this {FeedParserInstance} */
-FeedParser.prototype.handleCloseTag = function (el){
+FeedParser.prototype.handleCloseTag = function (el) {
var node = {
'#name': el,
'#prefix': '',
- '#local' : ''
+ '#local': ''
}
, stdEl
, item
@@ -322,15 +328,15 @@ FeedParser.prototype.handleCloseTag = function (el){
}
if (node['#name'] === 'item' ||
- node['#name'] === 'entry' ||
- (node['#local'] === 'item' && (node['#prefix'] === '' || node['#type'] === 'rdf')) ||
- (node['#local'] == 'entry' && (node['#prefix'] === '' || node['#type'] === 'atom'))) { // We have an article!
+ node['#name'] === 'entry' ||
+ (node['#local'] === 'item' && (node['#prefix'] === '' || node['#type'] === 'rdf')) ||
+ (node['#local'] == 'entry' && (node['#prefix'] === '' || node['#type'] === 'atom'))) { // We have an article!
isIllegallyNested = (
- ( node['#name'] === 'item' && this.stack[0]['#name'] === 'item' ) ||
- ( node['#name'] === 'entry' && this.stack[0]['#name'] === 'entry' ) ||
- ( (node['#local'] === 'item' && (node['#prefix'] === '' || node['#type'] === 'rdf')) && this.stack[0]['#name'] === 'item' ) ||
- ( (node['#local'] == 'entry' && (node['#prefix'] === '' || node['#type'] === 'atom')) && this.stack[0]['#name'] === 'entry' )
+ (node['#name'] === 'item' && this.stack[0]['#name'] === 'item') ||
+ (node['#name'] === 'entry' && this.stack[0]['#name'] === 'entry') ||
+ ((node['#local'] === 'item' && (node['#prefix'] === '' || node['#type'] === 'rdf')) && this.stack[0]['#name'] === 'item') ||
+ ((node['#local'] == 'entry' && (node['#prefix'] === '' || node['#type'] === 'atom')) && this.stack[0]['#name'] === 'entry')
);
if (isIllegallyNested) {
@@ -354,10 +360,10 @@ FeedParser.prototype.handleCloseTag = function (el){
if (this.meta.author && !item.author) item.author = this.meta.author;
this.push(item);
} else if (!this.meta.title && // We haven't yet parsed all the metadata
- (node['#name'] === 'channel' ||
- node['#name'] === 'feed' ||
- (node['#local'] === 'channel' && (node['#prefix'] === '' || node['#type'] === 'rdf')) ||
- (node['#local'] === 'feed' && (node['#prefix'] === '' || node['#type'] === 'atom')) ) ) {
+ (node['#name'] === 'channel' ||
+ node['#name'] === 'feed' ||
+ (node['#local'] === 'channel' && (node['#prefix'] === '' || node['#type'] === 'rdf')) ||
+ (node['#local'] === 'feed' && (node['#prefix'] === '' || node['#type'] === 'atom')))) {
_.assign(this.meta, this.handleMeta(n, this.meta['#type'], this.options));
if (!this._emitted_meta) {
this.emit('meta', this.meta);
@@ -387,7 +393,7 @@ FeedParser.prototype.handleCloseTag = function (el){
* @this {FeedParserInstance}
* @param {string} text
*/
-FeedParser.prototype.handleText = function (text){
+FeedParser.prototype.handleText = function (text) {
if (this.in_xhtml) {
this.xhtml['#'] += text;
} else {
@@ -427,7 +433,7 @@ FeedParser.prototype.handleAttributes = function handleAttributes (attrs, el) {
basepath = this.xmlbase[0]['#'];
}
- Object.keys(attrs).forEach(/** @this {FeedParserInstance} */ function(key){
+ Object.keys(attrs).forEach(/** @this {FeedParserInstance} */ function (key) {
var attr = attrs[key]
, ns = {}
, prefix = ''
@@ -442,9 +448,9 @@ FeedParser.prototype.handleAttributes = function handleAttributes (attrs, el) {
// If the feed is using a non-default prefix, we'll use it, too
// But we force the use of the 'xml' prefix
if (attr.uri && attr.prefix && !_.nslookup(attr.uri, attr.prefix) || _.nslookup(attr.uri, 'xml')) {
- prefix = ( _.nsprefix(attr.uri) || attr.prefix ) + ( attr.local ? ':' : '' );
+ prefix = (_.nsprefix(attr.uri) || attr.prefix) + (attr.local ? ':' : '');
}
- if (basepath && _.HTML_URI_ATTRS.has(attr.local)) {
+ if (basepath && HTML_URI_ATTRS.has(attr.local)) {
// Apply xml:base to these elements as they appear
// rather than leaving it to the ultimate parser
attr.value = _.resolveHtmlAttributeValue(basepath, attr.local, attr.value);
@@ -456,11 +462,11 @@ FeedParser.prototype.handleAttributes = function handleAttributes (attrs, el) {
// Per RFC 3986 ยง4.4, an empty or "#"-only xml:base is a same-document reference.
// It does not change the effective base URI, so skip pushing it.
if (attr.value && !/^#/.test(attr.value)) {
- this.xmlbase.unshift({ '#name': el, '#': attr.value});
+ this.xmlbase.unshift({ '#name': el, '#': attr.value });
}
} else if (attr.name === 'type' && attr.value === 'xhtml') {
this.in_xhtml = true;
- this.xhtml = {'#name': el, '#': ''};
+ this.xhtml = { '#name': el, '#': '' };
}
simplifiedAttributes[prefix + attr.local] = attr.value ? attr.value.trim() : '';
}, this);
@@ -470,8 +476,8 @@ FeedParser.prototype.handleAttributes = function handleAttributes (attrs, el) {
/**
* @this {FeedParserInstance}
* @param {ParsedNode} node
- * @param {import('../../index').Type} type
- * @param {import('../../index').Options} options
+ * @param {import('../index').Type} type
+ * @param {import('../index').Options} options
* @returns {Object}
*/
FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
@@ -482,7 +488,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
;
if (normalize) {
- ['title','description','date', 'pubdate', 'pubDate','link', 'xmlurl', 'xmlUrl','author','language','favicon','copyright','generator'].forEach(function (property){
+ ['title', 'description', 'date', 'pubdate', 'pubDate', 'link', 'xmlurl', 'xmlUrl', 'author', 'language', 'favicon', 'copyright', 'generator'].forEach(function (property) {
meta[property] = null;
});
meta.cloud = {};
@@ -490,24 +496,24 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
meta.categories = [];
}
- Object.keys(node).forEach(function(name){
+ Object.keys(node).forEach(function (name) {
var el = node[name];
if (normalize) {
- switch(name){
- case('title'):
+ switch (name) {
+ case ('title'):
meta.title = _.get(el);
break;
- case('description'):
- case('subtitle'):
+ case ('description'):
+ case ('subtitle'):
meta.description = _.get(el);
break;
- case('pubdate'):
- case('lastbuilddate'):
- case('published'):
- case('modified'):
- case('updated'):
- case('dc:date'):
+ case ('pubdate'):
+ case ('lastbuilddate'):
+ case ('published'):
+ case ('modified'):
+ case ('updated'):
+ case ('dc:date'):
var date = _.get(el) ? new Date(_.get(el)) : null;
if (!date) break;
if (meta.pubdate === null || name == 'pubdate' || name == 'published')
@@ -515,11 +521,11 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
if (meta.date === null || name == 'lastbuilddate' || name == 'modified' || name == 'updated')
meta.date = date;
break;
- case('link'):
- case('atom:link'):
- case('atom10:link'):
+ case ('link'):
+ case ('atom:link'):
+ case ('atom10:link'):
if (Array.isArray(el)) {
- el.forEach(function (link){
+ el.forEach(function (link) {
if (link['@']['href']) { // Atom
if (_.get(link['@'], 'rel')) {
if (link['@']['rel'] == 'alternate') {
@@ -546,7 +552,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
meta.link = _.get(link);
}
if (_.isAbsoluteUrl(meta.link) && this.xmlbase && this.xmlbase.length === 0) {
- this.xmlbase.unshift({ '#name': 'xml', '#': meta.link});
+ this.xmlbase.unshift({ '#name': 'xml', '#': meta.link });
this.stack[0] = _.reresolve(this.stack[0], meta.link);
}
else if (this.xmlbase && this.xmlbase.length > 0) {
@@ -562,7 +568,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
else if (el['@']['rel'] == 'self') {
meta.xmlurl = meta.xmlUrl = el['@']['href'];
if (_.isAbsoluteUrl(meta.xmlurl) && this.xmlbase && this.xmlbase.length === 0) {
- this.xmlbase.unshift({ '#name': 'xml', '#': meta.xmlurl});
+ this.xmlbase.unshift({ '#name': 'xml', '#': meta.xmlurl });
this.stack[0] = _.reresolve(this.stack[0], meta.xmlurl);
}
else if (this.xmlbase && this.xmlbase.length > 0) {
@@ -580,7 +586,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
if (!meta.link) meta.link = _.get(el);
}
if (_.isAbsoluteUrl(meta.link) && this.xmlbase && this.xmlbase.length === 0) {
- this.xmlbase.unshift({ '#name': 'xml', '#': meta.link});
+ this.xmlbase.unshift({ '#name': 'xml', '#': meta.link });
this.stack[0] = _.reresolve(this.stack[0], meta.link);
}
else if (this.xmlbase && this.xmlbase.length > 0) {
@@ -588,9 +594,9 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
}
}
break;
- case('managingeditor'):
- case('webmaster'):
- case('author'):
+ case ('managingeditor'):
+ case ('webmaster'):
+ case ('author'):
var author = {};
if (name == 'author') {
meta.author = _.get(el.name) || _.get(el.email) || _.get(el.uri);
@@ -606,7 +612,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
}
}
break;
- case('cloud'):
+ case ('cloud'):
// I can't believe someone actually would put two cloud elements in their channel
// but it happened
// Nevertheless, there can be only one
@@ -629,11 +635,11 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
}
meta.cloud.type = 'rsscloud';
break;
- case('language'):
+ case ('language'):
meta.language = _.get(el);
break;
- case('image'):
- case('logo'):
+ case ('image'):
+ case ('logo'):
if (el.url)
meta.image.url = _.get(el.url);
if (el.title)
@@ -641,46 +647,46 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
if (!meta.image.url && _.get(el))
meta.image.url = _.get(el);
break;
- case('icon'):
+ case ('icon'):
meta.favicon = _.get(el);
break;
- case('copyright'):
- case('rights'):
- case('dc:rights'):
+ case ('copyright'):
+ case ('rights'):
+ case ('dc:rights'):
meta.copyright = _.get(el);
break;
- case('generator'):
+ case ('generator'):
meta.generator = _.get(el);
if (_.get(el['@'], 'version'))
meta.generator += (meta.generator ? ' ' : '') + 'v' + el['@'].version;
if (_.get(el['@'], 'uri'))
meta.generator += meta.generator ? ' (' + el['@'].uri + ')' : el['@'].uri;
break;
- case('category'):
- case('dc:subject'):
- case('itunes:category'):
- case('media:category'):
+ case ('category'):
+ case ('dc:subject'):
+ case ('itunes:category'):
+ case ('media:category'):
/* We handle all the kinds of categories within the switch loop because meta.categories
- * is an array, unlike the other properties, and therefore can handle multiple values
- */
+ * is an array, unlike the other properties, and therefore can handle multiple values
+ */
var _category = ''
, _categories = []
- ;
+ ;
if (Array.isArray(el)) {
- el.forEach(function (category){
+ el.forEach(function (category) {
var _categoryValue;
if ('category' == name && 'atom' == type) {
if (category['@'] && (_categoryValue = _.safeTrim(_.get(category['@'], 'term')))) {
meta.categories.push(_categoryValue);
}
}
- else if ('category' == name && 'rss' == type){
+ else if ('category' == name && 'rss' == type) {
if ((_categoryValue = _.safeTrim(_.get(category)))) {
meta.categories.push(_categoryValue);
}
}
else if ('dc:subject' == name && (_categoryValue = _.safeTrim(_.get(category)))) {
- _categories = _categoryValue.split(' ').map(function (cat){ return cat.trim(); });
+ _categories = _categoryValue.split(' ').map(function (cat) { return cat.trim(); });
if (_categories.length) {
meta.categories = meta.categories.concat(_categories);
}
@@ -689,7 +695,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
if (category['@'] && _.safeTrim(_.get(category['@'], 'text'))) _category = _.safeTrim(_.get(category['@'], 'text'));
if (category[name]) {
if (Array.isArray(category[name])) {
- category[name].forEach(function (subcategory){
+ category[name].forEach(function (subcategory) {
var _subcategoryValue;
if (subcategory['@'] && (_subcategoryValue = _.safeTrim(_.get(subcategory['@'], 'text')))) {
meta.categories.push(_category + '/' + _subcategoryValue);
@@ -720,7 +726,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
}
}
else if ('dc:subject' == name && (_category = _.safeTrim(_.get(el)))) {
- _categories = _category.split(' ').map(function (cat){ return cat.trim(); });
+ _categories = _category.split(' ').map(function (cat) { return cat.trim(); });
if (_categories.length) {
meta.categories = meta.categories.concat(_categories);
}
@@ -729,7 +735,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
if (el['@'] && _.safeTrim(_.get(el['@'], 'text'))) _category = _.safeTrim(_.get(el['@'], 'text'));
if (el[name]) {
if (Array.isArray(el[name])) {
- el[name].forEach(function (subcategory){
+ el[name].forEach(function (subcategory) {
var _subcategoryValue;
if (subcategory['@'] && (_subcategoryValue = _.safeTrim(_.get(subcategory['@'], 'text')))) {
meta.categories.push(_category + '/' + _subcategoryValue);
@@ -824,11 +830,11 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
/**
* @this {FeedParserInstance}
* @param {ParsedNode} node
- * @param {import('../../index').Type} type
- * @param {import('../../index').Options} options
+ * @param {import('../index').Type} type
+ * @param {import('../index').Options} options
* @returns {Object}
*/
-FeedParser.prototype.handleItem = function handleItem (node, type, options){
+FeedParser.prototype.handleItem = function handleItem (node, type, options) {
if (!type || !node) return {};
var item = {}
@@ -836,7 +842,7 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
;
if (normalize) {
- ['title','description','summary','date','pubdate','pubDate','link','guid','author','comments', 'origlink'].forEach(function (property){
+ ['title', 'description', 'summary', 'date', 'pubdate', 'pubDate', 'link', 'guid', 'author', 'comments', 'origlink'].forEach(function (property) {
item[property] = null;
});
item.image = {};
@@ -845,30 +851,30 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
item.enclosures = [];
}
- Object.keys(node).forEach(function(name){
+ Object.keys(node).forEach(function (name) {
var el = node[name]
, attrs = _.get(el, '@')
, enclosure;
if (normalize) {
- switch(name){
- case('title'):
+ switch (name) {
+ case ('title'):
item.title = _.get(el);
break;
- case('description'):
- case('summary'):
+ case ('description'):
+ case ('summary'):
item.summary = _.get(el);
if (!item.description) item.description = _.get(el);
break;
- case('content'):
- case('content:encoded'):
+ case ('content'):
+ case ('content:encoded'):
item.description = _.get(el);
break;
- case('pubdate'):
- case('published'):
- case('issued'):
- case('modified'):
- case('updated'):
- case('dc:date'):
+ case ('pubdate'):
+ case ('published'):
+ case ('issued'):
+ case ('modified'):
+ case ('updated'):
+ case ('dc:date'):
var date = _.get(el) ? new Date(_.get(el)) : null;
if (!date) break;
if (item.pubdate === null || name == 'pubdate' || name == 'published' || name == 'issued')
@@ -876,9 +882,9 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
if (item.date === null || name == 'modified' || name == 'updated')
item.date = date;
break;
- case('link'):
+ case ('link'):
if (Array.isArray(el)) {
- el.forEach(function (link){
+ el.forEach(function (link) {
if (link['@']['href']) { // Atom
if (_.get(link['@'], 'rel')) {
if (link['@']['rel'] == 'canonical') item.origlink = link['@']['href'];
@@ -886,7 +892,7 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
if (link['@']['rel'] == 'self' && !item.link) item.link = link['@']['href'];
if (link['@']['rel'] == 'replies') item.comments = link['@']['href'];
if (link['@']['rel'] == 'enclosure') {
- enclosure = /** @type {import('../../index').Enclosure} */ ({});
+ enclosure = /** @type {import('../index').Enclosure} */ ({});
enclosure.url = link['@']['href'];
enclosure.type = _.get(link['@'], 'type');
enclosure.length = _.get(link['@'], 'length');
@@ -909,7 +915,7 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
if (el['@']['rel'] == 'self' && !item.link) item.link = el['@']['href'];
if (el['@']['rel'] == 'replies') item.comments = el['@']['href'];
if (el['@']['rel'] == 'enclosure') {
- enclosure = /** @type {import('../../index').Enclosure} */ ({});
+ enclosure = /** @type {import('../index').Enclosure} */ ({});
enclosure.url = el['@']['href'];
enclosure.type = _.get(el['@'], 'type');
enclosure.length = _.get(el['@'], 'length');
@@ -926,8 +932,8 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
}
if (!item.guid) item.guid = item.link;
break;
- case('guid'):
- case('id'):
+ case ('guid'):
+ case ('id'):
item.guid = _.get(el);
// http://cyber.law.harvard.edu/rss/rss.html#ltguidgtSubelementOfLtitemgt
// If the guid element has an attribute named "isPermaLink" with a value
@@ -941,7 +947,7 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
item.permalink = item.guid;
}
break;
- case('author'):
+ case ('author'):
var author = {};
if (_.get(el)) { // RSS
author = addressparser(_.get(el))[0];
@@ -958,13 +964,13 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
item.author = _.get(el.name) || _.get(el.email) || _.get(el.uri);
}
break;
- case('dc:creator'):
+ case ('dc:creator'):
item.author = _.get(el);
break;
- case('comments'):
+ case ('comments'):
item.comments = _.get(el);
break;
- case('source'):
+ case ('source'):
if ('rss' == type) {
item.source['title'] = _.get(el);
item.source['url'] = _.get(el['@'], 'url');
@@ -977,7 +983,7 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
if (item.source['url'] && !this.meta.xmlurl) {
this.meta.xmlurl = this.meta.xmlUrl = item.source['url'];
if (_.isAbsoluteUrl(item.source['url']) && this.xmlbase && this.xmlbase.length === 0) {
- this.xmlbase.unshift({ '#name': 'xml', '#': item.source['url']});
+ this.xmlbase.unshift({ '#name': 'xml', '#': item.source['url'] });
this.stack[0] = _.reresolve(this.stack[0], item.source['url']);
}
else if (this.xmlbase && this.xmlbase.length > 0) {
@@ -985,10 +991,10 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
}
}
break;
- case('enclosure'):
+ case ('enclosure'):
if (Array.isArray(el)) {
- el.forEach(function (enc){
- enclosure = /** @type {import('../../index').Enclosure} */ ({});
+ el.forEach(function (enc) {
+ enclosure = /** @type {import('../index').Enclosure} */ ({});
enclosure.url = _.get(enc['@'], 'url');
enclosure.type = _.get(enc['@'], 'type');
enclosure.length = _.get(enc['@'], 'length');
@@ -999,7 +1005,7 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
}
});
} else {
- enclosure = /** @type {import('../../index').Enclosure} */ ({});
+ enclosure = /** @type {import('../index').Enclosure} */ ({});
enclosure.url = _.get(el['@'], 'url');
enclosure.type = _.get(el['@'], 'type');
enclosure.length = _.get(el['@'], 'length');
@@ -1010,11 +1016,11 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
}
}
break;
- case('media:content'):
+ case ('media:content'):
var optionalAttributes = ['bitrate', 'framerate', 'samplingrate', 'duration', 'height', 'width'];
if (Array.isArray(el)) {
- el.forEach(function (enc){
- enclosure = /** @type {import('../../index').Enclosure} */ ({});
+ el.forEach(function (enc) {
+ enclosure = /** @type {import('../index').Enclosure} */ ({});
enclosure.url = _.get(enc['@'], 'url');
enclosure.type = _.get(enc['@'], 'type') || _.get(enc['@'], 'medium');
enclosure.length = _.get(enc['@'], 'filesize');
@@ -1032,7 +1038,7 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
}
});
} else {
- enclosure = /** @type {import('../../index').Enclosure} */ ({});
+ enclosure = /** @type {import('../index').Enclosure} */ ({});
enclosure.url = _.get(el['@'], 'url');
enclosure.type = _.get(el['@'], 'type') || _.get(el['@'], 'medium');
enclosure.length = _.get(el['@'], 'filesize');
@@ -1050,32 +1056,32 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
}
}
break;
- case('enc:enclosure'): // Can't find this in use for an example to debug. Only example found does not comply with the spec -- can't code THAT!
+ case ('enc:enclosure'): // Can't find this in use for an example to debug. Only example found does not comply with the spec -- can't code THAT!
break;
- case('category'):
- case('dc:subject'):
- case('itunes:category'):
- case('media:category'):
+ case ('category'):
+ case ('dc:subject'):
+ case ('itunes:category'):
+ case ('media:category'):
/* We handle all the kinds of categories within the switch loop because item.categories
- * is an array, unlike the other properties, and therefore can handle multiple values
- */
+ * is an array, unlike the other properties, and therefore can handle multiple values
+ */
var _category = ''
, _categories = []
- ;
+ ;
if (Array.isArray(el)) {
- el.forEach(function (category){
+ el.forEach(function (category) {
if ('category' == name && 'atom' == type) {
if (category['@'] && _.get(category['@'], 'term')) item.categories.push(_.get(category['@'], 'term'));
} else if ('category' == name && _.get(category) && 'rss' == type) {
item.categories.push(_.get(category).trim());
} else if ('dc:subject' == name && _.get(category)) {
- _categories = _.get(category).split(' ').map(function (cat){ return cat.trim(); });
+ _categories = _.get(category).split(' ').map(function (cat) { return cat.trim(); });
if (_categories.length) item.categories = item.categories.concat(_categories);
} else if ('itunes:category' == name) {
if (category['@'] && _.get(category['@'], 'text')) _category = _.get(category['@'], 'text');
if (category[name]) {
if (Array.isArray(category[name])) {
- category[name].forEach(function (subcategory){
+ category[name].forEach(function (subcategory) {
if (subcategory['@'] && _.get(subcategory['@'], 'text')) item.categories.push(_category + '/' + _.get(subcategory['@'], 'text'));
});
} else {
@@ -1095,13 +1101,13 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
} else if ('category' == name && _.get(el) && 'rss' == type) {
item.categories.push(_.get(el).trim());
} else if ('dc:subject' == name && _.get(el)) {
- _categories = _.get(el).split(' ').map(function (cat){ return cat.trim(); });
+ _categories = _.get(el).split(' ').map(function (cat) { return cat.trim(); });
if (_categories.length) item.categories = item.categories.concat(_categories);
} else if ('itunes:category' == name) {
if (el['@'] && _.get(el['@'], 'text')) _category = _.get(el['@'], 'text');
if (el[name]) {
if (Array.isArray(el[name])) {
- el[name].forEach(function (subcategory){
+ el[name].forEach(function (subcategory) {
if (subcategory['@'] && _.get(subcategory['@'], 'text')) item.categories.push(_category + '/' + _.get(subcategory['@'], 'text'));
});
} else {
@@ -1116,8 +1122,8 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options){
}
}
break;
- case('feedburner:origlink'):
- case('pheedo:origlink'):
+ case ('feedburner:origlink'):
+ case ('pheedo:origlink'):
if (!item.origlink) {
item.origlink = _.get(el);
}
@@ -1224,7 +1230,7 @@ FeedParser.prototype._flush = function (done) {
* @typedef {Object} FeedParserState
* Instance properties set up by FeedParser.prototype.init and the constructor.
* @property {Object} meta - Parsed feed metadata; shape evolves during parsing
- * @property {import('../../index').Options} options
+ * @property {import('../index').Options} options
* @property {Object.
} _namespaces
* @property {boolean} _emitted_meta
* @property {Array.} stack
@@ -1243,8 +1249,8 @@ FeedParser.prototype._flush = function (done) {
* @property {function(string): void} handleCloseTag
* @property {function(string): void} handleText
* @property {function(Object., string): Object.} handleAttributes
- * @property {function(ParsedNode, import('../../index').Type, import('../../index').Options): Object} handleMeta
- * @property {function(ParsedNode, import('../../index').Type, import('../../index').Options): Object} handleItem
+ * @property {function(ParsedNode, import('../index').Type, import('../index').Options): Object} handleMeta
+ * @property {function(ParsedNode, import('../index').Type, import('../index').Options): Object} handleItem
*/
/**
@@ -1257,14 +1263,14 @@ FeedParser.prototype[Symbol.asyncIterator] = async function* () {
var error = null;
var ended = false;
- function onReadable() {
+ function onReadable () {
if (resolve) { resolve(); resolve = null; }
}
- function onEnd() {
+ function onEnd () {
ended = true;
if (resolve) { resolve(); resolve = null; }
}
- function onError(err) {
+ function onError (err) {
error = err;
if (resolve) { resolve(); resolve = null; }
}
diff --git a/lib/utils.js b/lib/utils.js
index b6633b9..7a54fac 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -1,12 +1,7 @@
-var WHATWGURL = require('url').URL
- , namespaces = require('./namespaces')
- ;
+const { URL: WHATWGURL } = require('url');
+const { NAMESPACES, HTML_URI_ATTRS, HTML_TAGS } = require('./constants');
-exports.has = require('lodash.has');
-exports.assign = require('lodash.assign');
-exports.uniq = require('lodash.uniq');
-
-var _get = require('lodash.get');
+const _get = require('lodash.get');
/**
* lodash.get, but wrapped to provide a default subkey (a/k/a path) of "#"
* and defaultValue of "null"
@@ -41,7 +36,6 @@ function get (obj, subkey, defaultValue) {
return _get(obj, subkey, defaultValue);
}
}
-exports.get = get;
/**
* Safely trim a value if it's a String
@@ -55,7 +49,6 @@ function safeTrim (val) {
}
return val;
}
-exports.safeTrim = safeTrim;
/*
* Resolve a URL against a base URL, returning the original pathUrl if
@@ -75,22 +68,14 @@ function resolve (baseUrl, pathUrl) {
return pathUrl;
}
}
-exports.resolve = resolve;
-
-var HTML_URI_ATTRS = new Set([
- 'href',
- 'src',
- 'uri',
- 'srcset',
- 'cite',
- 'longdesc',
- 'action',
- 'background',
- 'data',
- 'poster'
-]);
-exports.HTML_URI_ATTRS = HTML_URI_ATTRS;
+/*
+ * Resolve the URLs in a srcset attribute value against a base URL.
+ * @param {string} baseUrl
+ * @param {string} candidate
+ * @returns {string}
+ * @private
+ */
function resolveSrcsetCandidate (baseUrl, candidate) {
var match = candidate.match(/^(\s*)(\S+)([\s\S]*)$/);
if (!match) return candidate;
@@ -118,7 +103,6 @@ function resolveSrcset (baseUrl, srcset) {
return out + resolveSrcsetCandidate(baseUrl, srcset.slice(start));
}
-exports.resolveSrcset = resolveSrcset;
function resolveHtmlAttributeValue (baseUrl, name, value) {
var attrName = name.toLowerCase();
@@ -126,7 +110,6 @@ function resolveHtmlAttributeValue (baseUrl, name, value) {
if (HTML_URI_ATTRS.has(attrName)) return resolve(baseUrl, value);
return value;
}
-exports.resolveHtmlAttributeValue = resolveHtmlAttributeValue;
/*
* Check whether a given uri is an absolute URL
@@ -142,7 +125,6 @@ function isAbsoluteUrl (uri) {
return false;
}
}
-exports.isAbsoluteUrl = isAbsoluteUrl;
/*
* Check whether a given namespace URI matches the given default
@@ -153,9 +135,8 @@ exports.isAbsoluteUrl = isAbsoluteUrl;
* @private
*/
function nslookup (uri, def) {
- return namespaces[uri] === def;
+ return NAMESPACES[uri] === def;
}
-exports.nslookup = nslookup;
/*
* Return the "default" namespace prefix for a given namespace URI
@@ -165,9 +146,8 @@ exports.nslookup = nslookup;
* @private
*/
function nsprefix (uri) {
- return namespaces[uri];
+ return NAMESPACES[uri];
}
-exports.nsprefix = nsprefix;
/*
* Walk a node and re-resolve the urls using the given baseurl
@@ -228,33 +208,6 @@ function reresolve (node, baseurl) {
return resolveLevel(node);
}
-exports.reresolve = reresolve;
-
-var HTML_TAGS = new Set([
- 'a', 'abbr', 'acronym', 'address', 'applet', 'area', 'article', 'aside', 'audio',
- 'b', 'base', 'basefont', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button',
- 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup',
- 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt',
- 'em', 'embed',
- 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset',
- 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html',
- 'i', 'iframe', 'img', 'input', 'ins', 'isindex',
- 'kbd',
- 'label', 'legend', 'li', 'link', 'listing',
- 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meta', 'meter', 'multicol',
- 'nav', 'nextid', 'nobr', 'noembed', 'noframes', 'noscript',
- 'object', 'ol', 'optgroup', 'option', 'output',
- 'p', 'param', 'picture', 'plaintext', 'pre', 'progress',
- 'q',
- 'rb', 'rp', 'rt', 'rtc', 'ruby',
- 's', 'samp', 'script', 'section', 'select', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup',
- 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th',
- 'thead', 'time', 'title', 'tr', 'track', 'tt',
- 'u', 'ul',
- 'var', 'video',
- 'wbr',
- 'xmp'
-]);
/*
* Scan markup starting at str[i] (which must be '<') and return its length
@@ -385,7 +338,6 @@ function resolveHtmlUris (html, baseUrl) {
}
return out;
}
-exports.resolveHtmlUris = resolveHtmlUris;
function mayHaveEmbeddedHtml (name, el) {
if (!el || typeof el['#'] !== 'string') return false;
@@ -401,7 +353,6 @@ function mayHaveEmbeddedHtml (name, el) {
return false;
}
-exports.mayHaveEmbeddedHtml = mayHaveEmbeddedHtml;
/*
* Strip HTML tags, leaving bare text content.
@@ -430,5 +381,17 @@ function stripHtml (str) {
return out;
}
-exports.HTML_TAGS = HTML_TAGS;
-exports.stripHtml = stripHtml;
+module.exports = {
+ get,
+ safeTrim,
+ resolve,
+ resolveSrcset,
+ resolveHtmlAttributeValue,
+ isAbsoluteUrl,
+ nslookup,
+ nsprefix,
+ reresolve,
+ resolveHtmlUris,
+ mayHaveEmbeddedHtml,
+ stripHtml
+};
diff --git a/test/api.js b/test/api.js
index 4be194f..cf40825 100644
--- a/test/api.js
+++ b/test/api.js
@@ -54,4 +54,4 @@ describe('api', function () {
});
});
-});
\ No newline at end of file
+});
diff --git a/test/async-iterator.js b/test/async-iterator.js
index ada8aea..e6ff940 100644
--- a/test/async-iterator.js
+++ b/test/async-iterator.js
@@ -4,7 +4,7 @@ var pipeline = require('util').promisify(require('stream').pipeline);
describe('async iterator usage', function () {
// These tests use .pipe() only to allow testing in older Node versions.
- // In modern Node versions, you can use pipeline() with async iterators
+ // In modern Node versions, you can use pipeline() with async iterators
// instead of .pipe(). If you use .pipe, you must add your own error handling
// to avoid uncaught exceptions on errors.
it('should work as an async iterator', async function () {
@@ -46,7 +46,7 @@ describe('async iterator usage', function () {
var items = [];
var caught = null;
var uncaught = null;
- function onUncaught(err) {
+ function onUncaught (err) {
uncaught = err;
}
process.prependOnceListener('uncaughtException', onUncaught);
diff --git a/test/bad.js b/test/bad.js
index b74b98e..dce6f4f 100644
--- a/test/bad.js
+++ b/test/bad.js
@@ -1,4 +1,4 @@
-describe('bad feeds', function(){
+describe('bad feeds', function () {
describe('not a feed', function () {
diff --git a/test/category.js b/test/category.js
index 1d77039..94f8d09 100644
--- a/test/category.js
+++ b/test/category.js
@@ -1,4 +1,4 @@
-describe('categories', function(){
+describe('categories', function () {
var feed = __dirname + '/feeds/category-feed.xml';
diff --git a/test/duplicate-enclosures.js b/test/duplicate-enclosures.js
index 8215489..725c10b 100644
--- a/test/duplicate-enclosures.js
+++ b/test/duplicate-enclosures.js
@@ -1,8 +1,8 @@
-describe('duplicate enclosures', function(){
+describe('duplicate enclosures', function () {
var feed = __dirname + '/feeds/mediacontent-dupes.xml';
- it('should not have duplicate enclosures from different elements', function (done){
+ it('should not have duplicate enclosures from different elements', function (done) {
fs.createReadStream(feed).pipe(new FeedParser())
.once('readable', function () {
var stream = this;
diff --git a/test/illegally-nested.js b/test/illegally-nested.js
index 642832c..fe465a7 100644
--- a/test/illegally-nested.js
+++ b/test/illegally-nested.js
@@ -1,8 +1,8 @@
-describe('illegally nested', function(){
+describe('illegally nested', function () {
var feed = __dirname + '/feeds/illegally-nested.xml';
- it('should ignore illegally-nested items', function (done){
+ it('should ignore illegally-nested items', function (done) {
var itemCount = 0;
fs.createReadStream(feed).pipe(new FeedParser())
.on('readable', function () {
diff --git a/test/link.js b/test/link.js
index 52d56ca..8996b3d 100644
--- a/test/link.js
+++ b/test/link.js
@@ -1,4 +1,4 @@
-describe('links', function(){
+describe('links', function () {
var feed = __dirname + '/feeds/non-text-alternate-links.xml';
@@ -20,7 +20,7 @@ describe('links', function(){
var items = [];
var sawDeprecation = false;
var origEmit = process.emit;
- process.emit = function(event, warning) {
+ process.emit = function (event, warning) {
if (event === 'warning' && warning && warning.name === 'DeprecationWarning') {
sawDeprecation = true;
}
diff --git a/test/namespaces.js b/test/namespaces.js
index fbced78..3ae393c 100644
--- a/test/namespaces.js
+++ b/test/namespaces.js
@@ -1,6 +1,6 @@
-describe('namespaced elements', function(){
+describe('namespaced elements', function () {
- describe('standard namespaces', function(){
+ describe('standard namespaces', function () {
var feed = __dirname + '/feeds/wapowellness.xml';
@@ -21,7 +21,7 @@ describe('namespaced elements', function(){
});
- describe('non-standard namespaces', function(){
+ describe('non-standard namespaces', function () {
var feed = __dirname + '/feeds/complexNamespaceFeed.xml';
@@ -41,7 +41,7 @@ describe('namespaced elements', function(){
});
- describe('nondefaultnamespace-baseline', function(){
+ describe('nondefaultnamespace-baseline', function () {
var feed = __dirname + '/feeds/nondefaultnamespace-baseline.atom';
@@ -62,7 +62,7 @@ describe('namespaced elements', function(){
});
- describe('nondefaultnamespace Test case 1', function(){
+ describe('nondefaultnamespace Test case 1', function () {
var feed = __dirname + '/feeds/nondefaultnamespace.atom';
@@ -83,7 +83,7 @@ describe('namespaced elements', function(){
});
- describe('nondefaultnamespace Test case 2', function(){
+ describe('nondefaultnamespace Test case 2', function () {
var feed = __dirname + '/feeds/nondefaultnamespace-xhtml.atom';
@@ -104,7 +104,7 @@ describe('namespaced elements', function(){
});
- describe('nondefaultnamespace Test case 3', function(){
+ describe('nondefaultnamespace Test case 3', function () {
var feed = __dirname + '/feeds/unknown-namespace.atom';
diff --git a/test/utils.js b/test/utils.js
index e81648d..94c7405 100644
--- a/test/utils.js
+++ b/test/utils.js
@@ -1,4 +1,5 @@
var utils = require('../lib/utils');
+var { HTML_TAGS } = require('../lib/constants');
describe('utils', function () {
@@ -459,7 +460,7 @@ describe('utils', function () {
assert.strictEqual(utils.stripHtml(' 0\'>link'), 'link');
});
- utils.HTML_TAGS.forEach(function (tag) {
+ HTML_TAGS.forEach(function (tag) {
it(`strips ${tag} HTML tag opening and closing and self-closing`, function () {
assert.strictEqual(utils.stripHtml('<' + tag + '>content' + tag + '> and <' + tag + ' />more'), 'content and more', 'expected <' + tag + '> to be stripped');
});
diff --git a/test/xmlbase.js b/test/xmlbase.js
index 1c73245..519230e 100644
--- a/test/xmlbase.js
+++ b/test/xmlbase.js
@@ -1,4 +1,4 @@
-describe('xmlbase', function(){
+describe('xmlbase', function () {
it('should resolve relative URIs in meta elements with no root xml:base', function (done) {
var feed = __dirname + '/feeds/intertwingly.atom';
From f0ca89bd4ceec0e1b235f6d08838167d5069f47e Mon Sep 17 00:00:00 2001
From: Dan MacTough
Date: Sun, 17 May 2026 10:49:24 -0400
Subject: [PATCH 3/3] Switch to arrow functions instead of passing thisArg
---
lib/feedparser.js | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/lib/feedparser.js b/lib/feedparser.js
index 67fee1c..9be6fb8 100644
--- a/lib/feedparser.js
+++ b/lib/feedparser.js
@@ -196,21 +196,21 @@ FeedParser.prototype.handleOpenTag = function (node) {
if (this.in_xhtml && this.xhtml['#name'] != n['#name']) { // We are in an xhtml node
// This builds the opening tag, e.g.,
this.xhtml['#'] += '<' + n['#name'];
- Object.keys(n['@']).forEach(function (name) {
+ Object.keys(n['@']).forEach((name) => {
this.xhtml['#'] += ' ' + name + '="' + n['@'][name] + '"';
- }, this);
+ });
this.xhtml['#'] += '>';
} else if (this.stack.length === 0 &&
(n['#name'] === 'rss' ||
(n['#local'] === 'rdf' && _.nslookup([n['#uri']], 'rdf')) ||
(n['#local'] === 'feed' && _.nslookup([n['#uri']], 'atom')))) {
- Object.keys(n['@']).forEach(function (name) {
+ Object.keys(n['@']).forEach((name) => {
var o = {};
if (name != 'version') {
o[name] = n['@'][name];
this.meta['@'].push(o);
}
- }, this);
+ });
switch (n['#local']) {
case 'rss':
this.meta['#type'] = 'rss';
@@ -433,7 +433,7 @@ FeedParser.prototype.handleAttributes = function handleAttributes (attrs, el) {
basepath = this.xmlbase[0]['#'];
}
- Object.keys(attrs).forEach(/** @this {FeedParserInstance} */ function (key) {
+ Object.keys(attrs).forEach(/** @type (key: string) => void */ (key) => {
var attr = attrs[key]
, ns = {}
, prefix = ''
@@ -469,7 +469,7 @@ FeedParser.prototype.handleAttributes = function handleAttributes (attrs, el) {
this.xhtml = { '#name': el, '#': '' };
}
simplifiedAttributes[prefix + attr.local] = attr.value ? attr.value.trim() : '';
- }, this);
+ });
return simplifiedAttributes;
};
@@ -496,7 +496,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
meta.categories = [];
}
- Object.keys(node).forEach(function (name) {
+ Object.keys(node).forEach((name) => {
var el = node[name];
if (normalize) {
@@ -525,7 +525,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
case ('atom:link'):
case ('atom10:link'):
if (Array.isArray(el)) {
- el.forEach(function (link) {
+ el.forEach((link) => {
if (link['@']['href']) { // Atom
if (_.get(link['@'], 'rel')) {
if (link['@']['rel'] == 'alternate') {
@@ -558,7 +558,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
else if (this.xmlbase && this.xmlbase.length > 0) {
meta.link = _.resolve(_.get(this.xmlbase[0], '#'), meta.link);
}
- }, this);
+ });
} else {
if (el['@']['href']) { // Atom
if (_.get(el['@'], 'rel')) {
@@ -762,7 +762,7 @@ FeedParser.prototype.handleMeta = function handleMeta (node, type, options) {
if (~name.indexOf(':')) meta[name] = el;
else meta[type + ':' + name] = el;
}
- }, this); // forEach end
+ }); // forEach end
if (normalize) {
if (!meta.description) {
@@ -851,7 +851,7 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options) {
item.enclosures = [];
}
- Object.keys(node).forEach(function (name) {
+ Object.keys(node).forEach((name) => {
var el = node[name]
, attrs = _.get(el, '@')
, enclosure;
@@ -1135,7 +1135,7 @@ FeedParser.prototype.handleItem = function handleItem (node, type, options) {
if (~name.indexOf(':')) item[name] = el;
else item[type + ':' + name] = el;
}
- }, this); // forEach end
+ }); // forEach end
if (normalize) {
if (!item.description) {