Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(feedhandler): Move logic of FeedHandler to function #912

Merged
merged 1 commit into from
Aug 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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