@@ -53,7 +53,7 @@ interface Feed {
53
53
items ?: FeedItem [ ] ;
54
54
}
55
55
56
- // TODO: Consume data as it is coming in
56
+ /** @deprecated Handler is no longer necessary; use `getFeed` or `parseFeed` instead. */
57
57
export class FeedHandler extends DomHandler {
58
58
feed ?: Feed ;
59
59
@@ -74,103 +74,108 @@ export class FeedHandler extends DomHandler {
74
74
}
75
75
76
76
onend ( ) : void {
77
- const feedRoot = getOneElement ( isValidFeed , this . dom ) ;
77
+ const feed = getFeed ( this . dom ) ;
78
78
79
- if ( ! feedRoot ) {
79
+ if ( feed ) {
80
+ this . feed = feed ;
81
+ this . handleCallback ( null ) ;
82
+ } else {
80
83
this . handleCallback ( new Error ( "couldn't find root of feed" ) ) ;
81
- return ;
82
84
}
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Get the feed object from the root of a DOM tree.
90
+ *
91
+ * @param dom - The DOM to to extract the feed from.
92
+ * @returns The feed.
93
+ */
94
+ export function getFeed ( dom : Node [ ] ) : Feed | null {
95
+ const feedRoot = getOneElement ( isValidFeed , dom ) ;
96
+
97
+ if ( ! feedRoot ) return null ;
98
+
99
+ const feed : Feed = { } ;
100
+
101
+ if ( feedRoot . name === "feed" ) {
102
+ const childs = feedRoot . children ;
103
+ feed . type = "atom" ;
104
+ addConditionally ( feed , "id" , "id" , childs ) ;
105
+ addConditionally ( feed , "title" , "title" , childs ) ;
106
+ const href = getAttribute ( "href" , getOneElement ( "link" , childs ) ) ;
107
+ if ( href ) {
108
+ feed . link = href ;
109
+ }
110
+ addConditionally ( feed , "description" , "subtitle" , childs ) ;
111
+
112
+ const updated = fetch ( "updated" , childs ) ;
113
+ if ( updated ) {
114
+ feed . updated = new Date ( updated ) ;
115
+ }
116
+
117
+ addConditionally ( feed , "author" , "email" , childs , true ) ;
118
+ feed . items = getElements ( "entry" , childs ) . map ( ( item ) => {
119
+ const entry : FeedItem = { } ;
120
+ const { children } = item ;
83
121
84
- const feed : Feed = { } ;
122
+ addConditionally ( entry , "id" , "id" , children ) ;
123
+ addConditionally ( entry , "title" , "title" , children ) ;
85
124
86
- if ( feedRoot . name === "feed" ) {
87
- const childs = feedRoot . children ;
88
- feed . type = "atom" ;
89
- addConditionally ( feed , "id" , "id" , childs ) ;
90
- addConditionally ( feed , "title" , "title" , childs ) ;
91
- const href = getAttribute ( "href" , getOneElement ( "link" , childs ) ) ;
125
+ const href = getAttribute ( "href" , getOneElement ( "link" , children ) ) ;
92
126
if ( href ) {
93
- feed . link = href ;
127
+ entry . link = href ;
94
128
}
95
- addConditionally ( feed , "description" , "subtitle" , childs ) ;
96
129
97
- const updated = fetch ( "updated" , childs ) ;
98
- if ( updated ) {
99
- feed . updated = new Date ( updated ) ;
130
+ const description =
131
+ fetch ( "summary" , children ) || fetch ( "content" , children ) ;
132
+ if ( description ) {
133
+ entry . description = description ;
100
134
}
101
135
102
- addConditionally ( feed , "author" , "email" , childs , true ) ;
103
- feed . items = getElements ( "entry" , childs ) . map ( ( item ) => {
104
- const entry : FeedItem = { } ;
105
- const { children } = item ;
106
-
107
- addConditionally ( entry , "id" , "id" , children ) ;
108
- addConditionally ( entry , "title" , "title" , children ) ;
136
+ const pubDate = fetch ( "updated" , children ) ;
137
+ if ( pubDate ) {
138
+ entry . pubDate = new Date ( pubDate ) ;
139
+ }
109
140
110
- const href = getAttribute (
111
- "href" ,
112
- getOneElement ( "link" , children )
113
- ) ;
114
- if ( href ) {
115
- entry . link = href ;
116
- }
117
-
118
- const description =
119
- fetch ( "summary" , children ) || fetch ( "content" , children ) ;
120
- if ( description ) {
121
- entry . description = description ;
122
- }
123
-
124
- const pubDate = fetch ( "updated" , children ) ;
125
- if ( pubDate ) {
126
- entry . pubDate = new Date ( pubDate ) ;
127
- }
141
+ entry . media = getMediaElements ( children ) ;
128
142
129
- entry . media = getMediaElements ( children ) ;
143
+ return entry ;
144
+ } ) ;
145
+ } else {
146
+ const childs =
147
+ getOneElement ( "channel" , feedRoot . children ) ?. children ?? [ ] ;
148
+ feed . type = feedRoot . name . substr ( 0 , 3 ) ;
149
+ feed . id = "" ;
130
150
131
- return entry ;
132
- } ) ;
133
- } else {
134
- const childs =
135
- getOneElement ( "channel" , feedRoot . children ) ?. children ?? [ ] ;
136
- feed . type = feedRoot . name . substr ( 0 , 3 ) ;
137
- feed . id = "" ;
138
-
139
- addConditionally ( feed , "title" , "title" , childs ) ;
140
- addConditionally ( feed , "link" , "link" , childs ) ;
141
- addConditionally ( feed , "description" , "description" , childs ) ;
142
-
143
- const updated = fetch ( "lastBuildDate" , childs ) ;
144
- if ( updated ) {
145
- feed . updated = new Date ( updated ) ;
146
- }
151
+ addConditionally ( feed , "title" , "title" , childs ) ;
152
+ addConditionally ( feed , "link" , "link" , childs ) ;
153
+ addConditionally ( feed , "description" , "description" , childs ) ;
147
154
148
- addConditionally ( feed , "author" , "managingEditor" , childs , true ) ;
149
-
150
- feed . items = getElements ( "item" , feedRoot . children ) . map (
151
- ( item : Element ) => {
152
- const entry : FeedItem = { } ;
153
- const { children } = item ;
154
- addConditionally ( entry , "id" , "guid" , children ) ;
155
- addConditionally ( entry , "title" , "title" , children ) ;
156
- addConditionally ( entry , "link" , "link" , children ) ;
157
- addConditionally (
158
- entry ,
159
- "description" ,
160
- "description" ,
161
- children
162
- ) ;
163
- const pubDate = fetch ( "pubDate" , children ) ;
164
- if ( pubDate ) entry . pubDate = new Date ( pubDate ) ;
165
- entry . media = getMediaElements ( children ) ;
166
- return entry ;
167
- }
168
- ) ;
155
+ const updated = fetch ( "lastBuildDate" , childs ) ;
156
+ if ( updated ) {
157
+ feed . updated = new Date ( updated ) ;
169
158
}
170
159
171
- this . feed = feed ;
172
- this . handleCallback ( null ) ;
160
+ addConditionally ( feed , "author" , "managingEditor" , childs , true ) ;
161
+
162
+ feed . items = getElements ( "item" , feedRoot . children ) . map (
163
+ ( item : Element ) => {
164
+ const entry : FeedItem = { } ;
165
+ const { children } = item ;
166
+ addConditionally ( entry , "id" , "guid" , children ) ;
167
+ addConditionally ( entry , "title" , "title" , children ) ;
168
+ addConditionally ( entry , "link" , "link" , children ) ;
169
+ addConditionally ( entry , "description" , "description" , children ) ;
170
+ const pubDate = fetch ( "pubDate" , children ) ;
171
+ if ( pubDate ) entry . pubDate = new Date ( pubDate ) ;
172
+ entry . media = getMediaElements ( children ) ;
173
+ return entry ;
174
+ }
175
+ ) ;
173
176
}
177
+
178
+ return feed ;
174
179
}
175
180
176
181
function getMediaElements ( where : Node | Node [ ] ) : FeedItemMedia [ ] {
@@ -234,7 +239,7 @@ function getOneElement(
234
239
return DomUtils . getElementsByTagName ( tagName , node , true , 1 ) [ 0 ] ;
235
240
}
236
241
function fetch ( tagName : string , where : Node | Node [ ] , recurse = false ) : string {
237
- return DomUtils . getText (
242
+ return DomUtils . textContent (
238
243
DomUtils . getElementsByTagName ( tagName , where , recurse , 1 )
239
244
) . trim ( ) ;
240
245
}
@@ -267,13 +272,13 @@ function isValidFeed(value: string) {
267
272
* Parse a feed.
268
273
*
269
274
* @param feed The feed that should be parsed, as a string.
270
- * @param options Optionally, options for parsing. When using this option , you should set `xmlMode` to `true`.
275
+ * @param options Optionally, options for parsing. When using this, you should set `xmlMode` to `true`.
271
276
*/
272
277
export function parseFeed (
273
278
feed : string ,
274
279
options : ParserOptions & DomHandlerOptions = { xmlMode : true }
275
- ) : Feed | undefined {
276
- const handler = new FeedHandler ( options ) ;
280
+ ) : Feed | null {
281
+ const handler = new DomHandler ( null , options ) ;
277
282
new Parser ( handler , options ) . end ( feed ) ;
278
- return handler . feed ;
283
+ return getFeed ( handler . dom ) ;
279
284
}
0 commit comments