view content_scripts/feed-probe.js @ 14:376a0e415bba

Properly handle non-text content in Atom feed elements The title, subtitle, summary and content elements of Atom feeds can all have non-text content. When parsing title and subtitle elements HTML and XHTML content will be stripped of any markup in order to keep it simple. In summary and content elements markup will be preserved. Element content of any other type as well as remote content in content elements will be ignored.
author Guido Berhoerster <guido+feed-preview@berhoerster.name>
date Mon, 10 Dec 2018 16:38:11 +0100
parents bc5cc170163c
children da483ce3832d
line wrap: on
line source

/*
 * Copyright (C) 2018 Guido Berhoerster <guido+feed-preview@berhoerster.name>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

'use strict';

const TIMEOUT_MAX = 800; // ms

function getFeeds() {
    let urlsFeeds = new Map();
    let elements = document.querySelectorAll(':-moz-any(link, a)[href]' +
            '[rel=alternate]:-moz-any([type="application/atom+xml"], ' +
            '[type="application/rss+xml"])');

    for (let element of elements) {
        if (!element.href.match(/^https?:\/\//)) {
            continue;
        }

        urlsFeeds.set(element.href, {
            href: element.href,
            title: element.title || browser.i18n.getMessage('defaultFeedTitle'),
            type: element.type
        })
    }

    return Array.from(urlsFeeds.values());
}

function probeLinkedFeeds() {
    if (document.documentElement.nodeName.toUpperCase() !== 'HTML') {
        return;
    }

    let feeds = getFeeds();
    if (feeds.length === 0) {
        return;
    }

    // the listener on the background page might not be ready, keep trying to
    // send the message with an exponential backoff until TIMEOUT_MAX is
    // reached
    let timeout = 0;
    let sendFeeds = () => {
        browser.runtime.sendMessage(feeds).catch(e => {
            timeout = (timeout > 0) ? timeout * 2 : 100;
            if (timeout > TIMEOUT_MAX) {
                console.log(`Error: failed to message the background page: ` +
                        ` ${e.message}`);
                return;
            }
            setTimeout(sendFeeds, timeout);
        });
    };
    setTimeout(sendFeeds, timeout);
}

probeLinkedFeeds();