view content_scripts/feed-probe.js @ 31:76e23b361e92

Allow feed reader addons to subscribe to the currently viewed feed Add a link element to the feed preview that points to the currently viewed feed in order to allow feed reader addons to subscribe to it.
author Guido Berhoerster <guido+feed-preview@berhoerster.name>
date Tue, 22 Jan 2019 14:40:06 +0100
parents da483ce3832d
children ede87e1004f9
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 === document.URL) {
            // do not indicate the availability of a feed if the current
            // document is already a feed preview
            continue;
        }

        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();