PageSourceSearch

https://taxprofessionalsnw.com/images/galleries/style/jquery/rss-feed/rss-feed.js

js taxprofessionalsnw.com collected 2026-10-08 07:25:16 UTC 11,817 bytes, 336 lines download raw bytes

1/*!
2 * jQuery RSS plugin — XML edition
3 * Fetches and parses raw RSS 2.0 / Atom XML instead of going through a JSON(P) proxy.
4 * Public API is unchanged: $(selector).rssfeed(url, options, callback)
5 */
6!function (t) {
7  "use strict";
8  var e = function (e, n, o, i) {
9
10	n = n.replace("http://", "");
11	n = n.replace("https://", "");
12
13    this.target = e;
14    this.url = n;
15    this.html = [];
16    this.effectQueue = [];
17    this.options = t.extend(
18      {
19        ssl: !0,
20        // Set host to a CORS-enabled XML proxy, or leave null to request the feed URL directly.
21        host: this.url,
22        limit: null,
23        key: null,
24        layoutTemplate: '<div class="rssBody"><ul class="rssFeed">{entries}</ul></div>',
25        entryTemplate: '<li class="rssRow"><h4><a href="{url}">{title}</a></h4><p>{shortBodyPlain}...</p></li>',
26        tokens: {},
27        outputMode: "xml",
28        dateFormat: "dddd MMM Do",
29        dateLocale: "en",
30        effect: "show",
31        offsetStart: !1,
32        offsetEnd: !1,
33        error: function () {
34          console.log("jQuery RSS: url doesn't link to a valid RSS/Atom feed");
35        },
36        onData: function () {},
37        success: function () {}
38      },
39      o || {}
40    );
41    this.callback = i || this.options.success;
42  };
43
44  e.htmlTags = ["doctype", "html", "head", "title", "base", "link", "meta", "style", "script", "noscript", "body", "article", "nav", "aside", "section", "header", "footer", "h1-h6", "hgroup", "address", "p", "hr", "pre", "blockquote", "ol", "ul", "li", "dl", "dt", "dd", "figure", "figcaption", "div", "table", "caption", "thead", "tbody", "tfoot", "tr", "th", "td", "col", "colgroup", "form", "fieldset", "legend", "label", "input", "button", "select", "datalist", "optgroup", "option", "textarea", "keygen", "output", "progress", "meter", "details", "summary", "command", "menu", "del", "ins", "img", "iframe", "embed", "object", "param", "video", "audio", "source", "canvas", "track", "map", "area", "a", "em", "strong", "i", "b", "u", "s", "small", "abbr", "q", "cite", "dfn", "sub", "sup", "time", "code", "kbd", "samp", "var", "mark", "bdi", "bdo", "ruby", "rt", "rp", "span", "br", "wbr"];
45
46  // --- Loading: request XML instead of JSONP ---------------------------------
47  e.prototype.load = function (e) {
48    var url;
49    if (this.options.host) {
50      // Route through a proxy/host that returns the raw feed XML.
51      url = "http" + (this.options.ssl ? "s" : "") + "://" + this.options.host + "?q=" + encodeURIComponent(this.url);
52      if (null !== this.options.limit) url += "&num=" + this.options.limit;
53      if (null !== this.options.key) url += "&key=" + this.options.key;
54    } else {
55      // Fetch the feed directly (requires the feed to be same-origin or CORS-enabled).
56      url = this.url;
57    }
58
59    t.ajax({
60      url: url,
61      type: "GET",
62      dataType: "xml",
63      success: e,
64      error: t.proxy(function () {
65        this.entries = [];
66        this.feed = null;
67        this.options.error.call(this);
68        if (this.effectQueue.length === 0 && t.isFunction(this.callback)) this.callback.call(this);
69      }, this)
70    });
71  };
72
73  // --- XML parsing helpers ----------------------------------------------------
74  e.prototype.getText = function (parent, tagName) {
75    if (!parent) return "";
76    var nodes = parent.getElementsByTagName(tagName);
77    if (!nodes || nodes.length === 0) return "";
78    return (nodes[0].textContent || "").trim();
79  };
80
81  e.prototype.parseXML = function (xmlDoc) {
82    var self = this;
83    var feed = { title: "", link: "", description: "", entries: [] };
84
85    if (!xmlDoc) return feed;
86
87    var channel = xmlDoc.getElementsByTagName("channel")[0];
88    var isAtom = !channel && xmlDoc.getElementsByTagName("feed").length > 0;
89
90    if (isAtom) {
91      var atomRoot = xmlDoc.getElementsByTagName("feed")[0];
92      feed.title = self.getText(atomRoot, "title");
93      feed.description = self.getText(atomRoot, "subtitle");
94      // Atom <link> uses href attribute.
95      var feedLinks = atomRoot.getElementsByTagName("link");
96      if (feedLinks.length) feed.link = feedLinks[0].getAttribute("href") || "";
97
98      var atomEntries = xmlDoc.getElementsByTagName("entry");
99      for (var i = 0; i < atomEntries.length; i++) {
100        feed.entries.push(self.parseAtomEntry(atomEntries[i]));
101      }
102    } else if (channel) {
103      feed.title = self.getText(channel, "title");
104      feed.link = self.getText(channel, "link");
105      feed.description = self.getText(channel, "description");
106
107      var items = channel.getElementsByTagName("item");
108      for (var j = 0; j < items.length; j++) {
109        feed.entries.push(self.parseRssItem(items[j]));
110      }
111    }
112
113    return feed;
114  };
115
116  e.prototype.parseRssItem = function (item) {
117    var content =
118      this.getText(item, "encoded") || // content:encoded
119      this.getText(item, "description");
120    return {
121      title: this.getText(item, "title"),
122      link: this.getText(item, "link"),
123      author: this.getText(item, "creator") || this.getText(item, "author"),
124      publishedDate: this.getText(item, "pubDate") || this.getText(item, "date"),
125      content: content,
126      contentSnippet: content.replace(/<\/?[^>]+>/gi, "")
127    };
128  };
129
130  e.prototype.parseAtomEntry = function (entry) {
131    var content = this.getText(entry, "content") || this.getText(entry, "summary");
132    var link = "";
133    var links = entry.getElementsByTagName("link");
134    if (links.length) link = links[0].getAttribute("href") || "";
135
136    // Atom author is nested: <author><name>...</name></author>
137    var author = "";
138    var authorNode = entry.getElementsByTagName("author")[0];
139    if (authorNode) author = this.getText(authorNode, "name");
140
141    return {
142      title: this.getText(entry, "title"),
143      link: link,
144      author: author,
145      publishedDate: this.getText(entry, "published") || this.getText(entry, "updated"),
146      content: content,
147      contentSnippet: content.replace(/<\/?[^>]+>/gi, "")
148    };
149  };
150
151  // --- Rendering --------------------------------------------------------------
152  e.prototype.render = function () {
153    var e = this;
154    this.load(function (xmlDoc) {
155      try {
156        e.feed = e.parseXML(xmlDoc);
157        e.entries = e.feed.entries;
158        if (!e.feed || e.entries.length === 0) {
159          // Still allow empty render below, but a totally unparseable doc -> error.
160          if (!e.feed) throw new Error("no feed");
161        }
162      } catch (t) {
163        e.entries = [];
164        e.feed = null;
165        return e.options.error.call(e);
166      }
167
168      var o = e.generateHTMLForEntries();
169      e.target.append(o.layout);
170
171      if (0 !== o.entries.length) {
172        t.isFunction(e.options.onData) && e.options.onData.call(e);
173        var i = t(o.layout).is("entries") ? o.layout : t("entries", o.layout);
174        e.appendEntriesAndApplyEffects(i, o.entries);
175      }
176
177      e.effectQueue.length > 0
178        ? e.executeEffectQueue(e.callback)
179        : t.isFunction(e.callback) && e.callback.call(e);
180    });
181  };
182
183  e.prototype.appendEntriesAndApplyEffects = function (e, n) {
184    var o = this;
185    t.each(n, function (t, n) {
186      var i = o.wrapContent(n);
187      "show" === o.options.effect
188        ? e.before(i)
189        : (i.css({ display: "none" }), e.before(i), o.applyEffect(i, o.options.effect));
190    });
191    e.remove();
192  };
193
194  e.prototype.generateHTMLForEntries = function () {
195    var e = this,
196      n = { entries: [], layout: null },
197      // The feed itself returns every item, so honour `limit` here on the client.
198      l = null == e.options.limit ? null : parseInt(e.options.limit, 10);
199    if (null !== l && (isNaN(l) || l < 0)) l = null;
200    t(this.entries).each(function (index) {
201      var t,
202        o = this,
203        i = e.options.offsetStart,
204        s = e.options.offsetEnd;
205      if (null !== l && n.entries.length >= l) return !1;
206      i && s
207        ? index >= i &&
208          index <= s &&
209          e.isRelevant(o, n.entries) &&
210          ((t = e.evaluateStringForEntry(e.options.entryTemplate, o)), n.entries.push(t))
211        : e.isRelevant(o, n.entries) &&
212          ((t = e.evaluateStringForEntry(e.options.entryTemplate, o)), n.entries.push(t));
213    });
214    this.options.entryTemplate
215      ? (n.layout = this.wrapContent(this.options.layoutTemplate.replace("{entries}", "<entries></entries>")))
216      : (n.layout = this.wrapContent("<div><entries></entries></div>"));
217    return n;
218  };
219
220  e.prototype.wrapContent = function (e) {
221    return t(0 !== t.trim(e).indexOf("<") ? "<div>" + e + "</div>" : e);
222  };
223
224  e.prototype.applyEffect = function (t, e, n) {
225    var o = this;
226    switch (e) {
227      case "slide":
228        t.slideDown("slow", n);
229        break;
230      case "slideFast":
231        t.slideDown(n);
232        break;
233      case "slideSynced":
234        o.effectQueue.push({ element: t, effect: "slide" });
235        break;
236      case "slideFastSynced":
237        o.effectQueue.push({ element: t, effect: "slideFast" });
238    }
239  };
240
241  e.prototype.executeEffectQueue = function (t) {
242    var e = this;
243    this.effectQueue.reverse();
244    var n = function () {
245      var o = e.effectQueue.pop();
246      o ? e.applyEffect(o.element, o.effect, n) : t && t();
247    };
248    n();
249  };
250
251  e.prototype.evaluateStringForEntry = function (e, n) {
252    var o = e,
253      i = this;
254    t(e.match(/(\{.*?\})/g)).each(function () {
255      var t = this.toString();
256      o = o.replace(t, i.getValueForToken(t, n));
257    });
258    return o;
259  };
260
261  e.prototype.isRelevant = function (t, e) {
262    var n = this.getTokenMap(t);
263    return (
264      !this.options.filter ||
265      ((!this.options.filterLimit || this.options.filterLimit !== e.length) && this.options.filter(t, n))
266    );
267  };
268
269  e.prototype.getFormattedDate = function (t) {
270    if (this.options.dateFormatFunction) return this.options.dateFormatFunction(t);
271    if ("undefined" != typeof moment) {
272      var e = moment(new Date(t));
273      return (e = e.locale ? e.locale(this.options.dateLocale) : e.lang(this.options.dateLocale)).format(
274        this.options.dateFormat
275      );
276    }
277    return t;
278  };
279
280  e.prototype.getTokenMap = function (n) {
281    if (!this.feedTokens) {
282      var o = JSON.parse(JSON.stringify(this.feed));
283      delete o.entries;
284      this.feedTokens = o;
285    }
286    return t.extend(
287      {
288        feed: this.feedTokens,
289        url: n.link,
290        author: n.author,
291        date: this.getFormattedDate(n.publishedDate),
292        title: n.title,
293        body: n.content,
294        shortBody: n.contentSnippet,
295        bodyPlain: (function (t) {
296          for (
297            var n = t.content.replace(/<script[\r\s\S]*<\/script>/gim, "").replace(/<\/?[^>]+>/gi, ""), o = 0;
298            o < e.htmlTags.length;
299            o++
300          )
301            n = n.replace(new RegExp("<" + e.htmlTags[o], "gi"), "");
302          return n;
303        })(n),
304        shortBodyPlain: n.contentSnippet.replace(/<\/?[^>]+>/gi, ""),
305        index: t.inArray(n, this.entries),
306        totalEntries: this.entries.length,
307        teaserImage: (function (t) {
308          try {
309            return t.content.match(/(<img.*?>)/gi)[0];
310          } catch (t) {
311            return "";
312          }
313        })(n),
314        teaserImageUrl: (function (t) {
315          try {
316            return t.content.match(/(<img.*?>)/gi)[0].match(/src="(.*?)"/)[1];
317          } catch (t) {
318            return "";
319          }
320        })(n)
321      },
322      this.options.tokens
323    );
324  };
325
326  e.prototype.getValueForToken = function (t, e) {
327    var n = this.getTokenMap(e),
328      o = n[t.replace(/[\{\}]/g, "")];
329    if (void 0 !== o) return "function" == typeof o ? o(e, n) : o;
330    throw new Error("Unknown token: " + t + ", url:" + this.url);
331  };
332
333  t.fn.rssfeed = function (t, n, o) {
334    return new e(this, t, n, o).render(), this;
335  };
336}(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.