Skip to content

Commit

Permalink
refactor(feedhandler): Move logic of FeedHandler to function (#912)
Browse files Browse the repository at this point in the history
  • Loading branch information
fb55 authored Aug 20, 2021
1 parent 39a8109 commit 3a672ff
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 87 deletions.
177 changes: 91 additions & 86 deletions src/FeedHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ interface Feed {
items?: FeedItem[];
}

// TODO: Consume data as it is coming in
/** @deprecated Handler is no longer necessary; use `getFeed` or `parseFeed` instead. */
export class FeedHandler extends DomHandler {
feed?: Feed;

Expand All @@ -74,103 +74,108 @@ export class FeedHandler extends DomHandler {
}

onend(): void {
const feedRoot = getOneElement(isValidFeed, this.dom);
const feed = getFeed(this.dom);

if (!feedRoot) {
if (feed) {
this.feed = feed;
this.handleCallback(null);
} else {
this.handleCallback(new Error("couldn't find root of feed"));
return;
}
}
}

/**
* Get the feed object from the root of a DOM tree.
*
* @param dom - The DOM to to extract the feed from.
* @returns The feed.
*/
export function getFeed(dom: Node[]): Feed | null {
const feedRoot = getOneElement(isValidFeed, dom);

if (!feedRoot) return null;

const feed: Feed = {};

if (feedRoot.name === "feed") {
const childs = feedRoot.children;
feed.type = "atom";
addConditionally(feed, "id", "id", childs);
addConditionally(feed, "title", "title", childs);
const href = getAttribute("href", getOneElement("link", childs));
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);
feed.items = getElements("entry", childs).map((item) => {
const entry: FeedItem = {};
const { children } = item;

const feed: Feed = {};
addConditionally(entry, "id", "id", children);
addConditionally(entry, "title", "title", children);

if (feedRoot.name === "feed") {
const childs = feedRoot.children;
feed.type = "atom";
addConditionally(feed, "id", "id", childs);
addConditionally(feed, "title", "title", childs);
const href = getAttribute("href", getOneElement("link", childs));
const href = getAttribute("href", getOneElement("link", children));
if (href) {
feed.link = href;
entry.link = href;
}
addConditionally(feed, "description", "subtitle", childs);

const updated = fetch("updated", childs);
if (updated) {
feed.updated = new Date(updated);
const description =
fetch("summary", children) || fetch("content", children);
if (description) {
entry.description = description;
}

addConditionally(feed, "author", "email", childs, true);
feed.items = getElements("entry", childs).map((item) => {
const entry: FeedItem = {};
const { children } = item;

addConditionally(entry, "id", "id", children);
addConditionally(entry, "title", "title", children);
const pubDate = fetch("updated", children);
if (pubDate) {
entry.pubDate = new Date(pubDate);
}

const href = getAttribute(
"href",
getOneElement("link", children)
);
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);
}
entry.media = getMediaElements(children);

entry.media = getMediaElements(children);
return entry;
});
} else {
const childs =
getOneElement("channel", feedRoot.children)?.children ?? [];
feed.type = feedRoot.name.substr(0, 3);
feed.id = "";

return entry;
});
} else {
const childs =
getOneElement("channel", feedRoot.children)?.children ?? [];
feed.type = feedRoot.name.substr(0, 3);
feed.id = "";

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, "title", "title", childs);
addConditionally(feed, "link", "link", childs);
addConditionally(feed, "description", "description", childs);

addConditionally(feed, "author", "managingEditor", childs, true);

feed.items = getElements("item", feedRoot.children).map(
(item: Element) => {
const entry: FeedItem = {};
const { children } = item;
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);
if (pubDate) entry.pubDate = new Date(pubDate);
entry.media = getMediaElements(children);
return entry;
}
);
const updated = fetch("lastBuildDate", childs);
if (updated) {
feed.updated = new Date(updated);
}

this.feed = feed;
this.handleCallback(null);
addConditionally(feed, "author", "managingEditor", childs, true);

feed.items = getElements("item", feedRoot.children).map(
(item: Element) => {
const entry: FeedItem = {};
const { children } = item;
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);
if (pubDate) entry.pubDate = new Date(pubDate);
entry.media = getMediaElements(children);
return entry;
}
);
}

return feed;
}

function getMediaElements(where: Node | Node[]): FeedItemMedia[] {
Expand Down Expand Up @@ -234,7 +239,7 @@ function getOneElement(
return DomUtils.getElementsByTagName(tagName, node, true, 1)[0];
}
function fetch(tagName: string, where: Node | Node[], recurse = false): string {
return DomUtils.getText(
return DomUtils.textContent(
DomUtils.getElementsByTagName(tagName, where, recurse, 1)
).trim();
}
Expand Down Expand Up @@ -267,13 +272,13 @@ function isValidFeed(value: string) {
* Parse a feed.
*
* @param feed The feed that should be parsed, as a string.
* @param options Optionally, options for parsing. When using this option, you should set `xmlMode` to `true`.
* @param options Optionally, options for parsing. When using this, you should set `xmlMode` to `true`.
*/
export function parseFeed(
feed: string,
options: ParserOptions & DomHandlerOptions = { xmlMode: true }
): Feed | undefined {
const handler = new FeedHandler(options);
): Feed | null {
const handler = new DomHandler(null, options);
new Parser(handler, options).end(feed);
return handler.feed;
return getFeed(handler.dom);
}
2 changes: 1 addition & 1 deletion src/__fixtures__/test-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ interface TestFile {
* @param getResult Function to be called with the actual results.
*/
export function createSuite(
name: string,
name: "Events" | "Feeds" | "Stream",
getResult: (
file: TestFile,
done: (error: Error | null, actual?: unknown | unknown[]) => void
Expand Down

0 comments on commit 3a672ff

Please sign in to comment.