view util.js @ 63:ee1df80a1715 default tip

Nicer-looking input form
author mathieui
date Sun, 24 May 2020 14:19:29 +0200
parents 6d861d881b96
children
line wrap: on
line source

// SPDX-License-Identifier: AGPL-3.0-only
/*
 * Copyright © 2018-2020 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
 * Copyright © 2020 Mathieu Pasquet <mathieui@mathieui.net>
 *
 * Released under GNU AGPL v3 only, read the file 'LICENSE' for more information.
 */

'use strict';

const NS = {
    xrd: 'http://docs.oasis-open.org/ns/xri/xrd-1.0',
    roster: 'jabber:iq:roster',
    disco_items: 'http://jabber.org/protocol/disco#items',
    disco_info: 'http://jabber.org/protocol/disco#info',
    dataforms: 'jabber:x:data',
    pubsub: 'http://jabber.org/protocol/pubsub',
    pubsub_owner: 'http://jabber.org/protocol/pubsub#owner',
    avatar_metadata: 'urn:xmpp:avatar:metadata',
    avatar_data: 'urn:xmpp:avatar:data',
    nickname: 'http://jabber.org/protocol/nick',
    vcard4: 'urn:ietf:params:xml:ns:vcard-4.0',
    mam: 'urn:xmpp:mam:2',
    forward: 'urn:xmpp:forward:0',
};

function nsResolver(prefix) {
    return NS[prefix] || null;
}

function parseXPath(elem, xpath, result)
{
    if (result === undefined)
        result = XPathResult.FIRST_ORDERED_NODE_TYPE;
    const value = elem.getRootNode().evaluate(xpath, elem, nsResolver, result, null);
    if (result == XPathResult.FIRST_ORDERED_NODE_TYPE)
        return value.singleNodeValue;
    return value;
}

function parseXPathText(elem, xpath)
{
    const value = parseXPath(elem, xpath);
    if (value === null)
        return null;
    return value.textContent;
}

function configurePEPField(node, key, value, cb, err_cb) {
    return $iq({type: 'set'})
        .c('pubsub', {xmlns: 'http://jabber.org/protocol/pubsub#owner'})
            .c('configure', {node: node})
                .c('x', {xmlns: 'jabber:x:data', type: 'submit'})
                    .c('field', {'var': 'FORM_TYPE', type: 'hidden'})
                        .c('value')
                            .t('http://jabber.org/protocol/pubsub#node_config')
                            .up()
                        .up()
                    .c('field', {'var': key})
                        .c('value')
                            .t(value)
                            .up()
                        .up();
}

function parseErrorIq(iq) {
    // TODO: actually check that it is the first one.
    const error = iq.firstChild;
    if (error.namespaceURI !== 'jabber:client' || error.localName !== 'error')
        return null;
    const condition = error.firstChild;
    if (condition.namespaceURI !== 'urn:ietf:params:xml:ns:xmpp-stanzas')
        return null;
    const text = error.lastChild;
    if (text === condition)
        return condition.localName;
    if (text.namespaceURI !== 'urn:ietf:params:xml:ns:xmpp-stanzas' || text.localName !== 'text')
        return null;
    return condition.localName + ': ' + text.textContent;
}

function retrieveConfiguration(connection, node)
{
    return new Promise((resolve, reject) => {
        const iq = $iq({type: 'get'})
            .c('pubsub', {xmlns: 'http://jabber.org/protocol/pubsub#owner'})
                .c('configure', {node: node});
        connection.sendIQ(iq, onNodeConfigure.bind(null, resolve, reject), reject);
    });
}

function onNodeConfigure(resolve, reject, result_iq)
{
    const fields = parseXPath(result_iq, './pubsub_owner:pubsub/pubsub_owner:configure/dataforms:x/dataforms:field', XPathResult.UNORDERED_NODE_ITERATOR_TYPE);
    if (fields === null)
        return reject('no fields');
    let access_model = null;
    while (true) {
        const field = fields.iterateNext();
        if (field === null)
            break;
        const var_ = field.getAttributeNS(null, 'var');
        if (var_ === 'pubsub#access_model') {
            const value = parseXPath(field, './dataforms:value');
            access_model = value.textContent;
        }
    }
    return resolve(access_model);
}

function displaySpinner(spinner) {
    if ('timeoutid' in spinner.dataset)
        clearTimeout(spinner.dataset.timeoutid);
    spinner.src = 'spinner.svg';
    spinner.title = '';
    spinner.hidden = false;
}

function spinnerOk(spinner) {
    if ('timeoutid' in spinner.dataset)
        clearTimeout(spinner.dataset.timeoutid);
    spinner.src = 'ok.svg';
    spinner.title = '';
    spinner.hidden = false;
    spinner.dataset.timeoutid = setTimeout(function () {
        spinner.hidden = true;
    }, 1000);
}

function spinnerError(spinner, title) {
    if ('timeoutid' in spinner.dataset)
        clearTimeout(spinner.dataset.timeoutid);
    spinner.src = 'error.svg';
    spinner.title = title ? title : '';
    spinner.hidden = false;
}

function hideSpinner(spinner) {
    if ('timeoutid' in spinner.dataset)
        clearTimeout(spinner.dataset.timeoutid);
    spinner.hidden = true;
}