view content_scripts/feed-probe.js @ 6:5d7c13e998e9

Create feed previews using a stream filter Instead of replacing the feed document with an XHTML preview from a content script after it has already been rendered, create an XHTML preview using a stream filter before it is passed into the rendering engine and use an XSL style sheet to convert it to HTML. This has two advantages, firstly it results in an HTMLDocument with the full HTML DOM available and secondly it avoids rendering the document twice. Refactor the feed preview creation and split parsing and rendering into seperate modules.
author Guido Berhoerster <guido+feed-preview@berhoerster.name>
date Thu, 08 Nov 2018 16:30:34 +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();