Spaces:
Configuration error
Configuration error
File size: 5,981 Bytes
a053984 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
import { textContent } from "./stringify.js";
import { getElementsByTagName } from "./legacy.js";
/**
* Get the feed object from the root of a DOM tree.
*
* @category Feeds
* @param doc - The DOM to to extract the feed from.
* @returns The feed.
*/
export function getFeed(doc) {
const feedRoot = getOneElement(isValidFeed, doc);
return !feedRoot
? null
: feedRoot.name === "feed"
? getAtomFeed(feedRoot)
: getRssFeed(feedRoot);
}
/**
* Parse an Atom feed.
*
* @param feedRoot The root of the feed.
* @returns The parsed feed.
*/
function getAtomFeed(feedRoot) {
var _a;
const childs = feedRoot.children;
const feed = {
type: "atom",
items: getElementsByTagName("entry", childs).map((item) => {
var _a;
const { children } = item;
const entry = { media: getMediaElements(children) };
addConditionally(entry, "id", "id", children);
addConditionally(entry, "title", "title", children);
const href = (_a = getOneElement("link", children)) === null || _a === void 0 ? void 0 : _a.attribs["href"];
if (href) {
entry.link = href;
}
const description = fetch("summary", children) || fetch("content", children);
if (description) {
entry.description = description;
}
const pubDate = fetch("updated", children);
if (pubDate) {
entry.pubDate = new Date(pubDate);
}
return entry;
}),
};
addConditionally(feed, "id", "id", childs);
addConditionally(feed, "title", "title", childs);
const href = (_a = getOneElement("link", childs)) === null || _a === void 0 ? void 0 : _a.attribs["href"];
if (href) {
feed.link = href;
}
addConditionally(feed, "description", "subtitle", childs);
const updated = fetch("updated", childs);
if (updated) {
feed.updated = new Date(updated);
}
addConditionally(feed, "author", "email", childs, true);
return feed;
}
/**
* Parse a RSS feed.
*
* @param feedRoot The root of the feed.
* @returns The parsed feed.
*/
function getRssFeed(feedRoot) {
var _a, _b;
const childs = (_b = (_a = getOneElement("channel", feedRoot.children)) === null || _a === void 0 ? void 0 : _a.children) !== null && _b !== void 0 ? _b : [];
const feed = {
type: feedRoot.name.substr(0, 3),
id: "",
items: getElementsByTagName("item", feedRoot.children).map((item) => {
const { children } = item;
const entry = { media: getMediaElements(children) };
addConditionally(entry, "id", "guid", children);
addConditionally(entry, "title", "title", children);
addConditionally(entry, "link", "link", children);
addConditionally(entry, "description", "description", children);
const pubDate = fetch("pubDate", children) || fetch("dc:date", children);
if (pubDate)
entry.pubDate = new Date(pubDate);
return entry;
}),
};
addConditionally(feed, "title", "title", childs);
addConditionally(feed, "link", "link", childs);
addConditionally(feed, "description", "description", childs);
const updated = fetch("lastBuildDate", childs);
if (updated) {
feed.updated = new Date(updated);
}
addConditionally(feed, "author", "managingEditor", childs, true);
return feed;
}
const MEDIA_KEYS_STRING = ["url", "type", "lang"];
const MEDIA_KEYS_INT = [
"fileSize",
"bitrate",
"framerate",
"samplingrate",
"channels",
"duration",
"height",
"width",
];
/**
* Get all media elements of a feed item.
*
* @param where Nodes to search in.
* @returns Media elements.
*/
function getMediaElements(where) {
return getElementsByTagName("media:content", where).map((elem) => {
const { attribs } = elem;
const media = {
medium: attribs["medium"],
isDefault: !!attribs["isDefault"],
};
for (const attrib of MEDIA_KEYS_STRING) {
if (attribs[attrib]) {
media[attrib] = attribs[attrib];
}
}
for (const attrib of MEDIA_KEYS_INT) {
if (attribs[attrib]) {
media[attrib] = parseInt(attribs[attrib], 10);
}
}
if (attribs["expression"]) {
media.expression = attribs["expression"];
}
return media;
});
}
/**
* Get one element by tag name.
*
* @param tagName Tag name to look for
* @param node Node to search in
* @returns The element or null
*/
function getOneElement(tagName, node) {
return getElementsByTagName(tagName, node, true, 1)[0];
}
/**
* Get the text content of an element with a certain tag name.
*
* @param tagName Tag name to look for.
* @param where Node to search in.
* @param recurse Whether to recurse into child nodes.
* @returns The text content of the element.
*/
function fetch(tagName, where, recurse = false) {
return textContent(getElementsByTagName(tagName, where, recurse, 1)).trim();
}
/**
* Adds a property to an object if it has a value.
*
* @param obj Object to be extended
* @param prop Property name
* @param tagName Tag name that contains the conditionally added property
* @param where Element to search for the property
* @param recurse Whether to recurse into child nodes.
*/
function addConditionally(obj, prop, tagName, where, recurse = false) {
const val = fetch(tagName, where, recurse);
if (val)
obj[prop] = val;
}
/**
* Checks if an element is a feed root node.
*
* @param value The name of the element to check.
* @returns Whether an element is a feed root node.
*/
function isValidFeed(value) {
return value === "rss" || value === "feed" || value === "rdf:RDF";
}
//# sourceMappingURL=feeds.js.map |