Commit 0ca2e5ae authored by JC Brand's avatar JC Brand

Remove need for lodash templates in headless build

parent 3fc6f7fa
/*global mock */ /*global mock, converse */
const Strophe = converse.env.Strophe; const Strophe = converse.env.Strophe;
const $iq = converse.env.$iq; const $iq = converse.env.$iq;
...@@ -391,7 +391,7 @@ describe("XEP-0363: HTTP File Upload", function () { ...@@ -391,7 +391,7 @@ describe("XEP-0363: HTTP File Upload", function () {
u.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '0.5') u.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '0.5')
.then(() => { .then(() => {
message.set('progress', 1); message.set('progress', 1);
u.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '1') u.waitUntil(() => view.el.querySelector('.chat-content progress')?.getAttribute('value') === '1')
}).then(() => { }).then(() => {
message.save({ message.save({
'upload': _converse.SUCCESS, 'upload': _converse.SUCCESS,
......
...@@ -39,13 +39,12 @@ mock.initConverse = function (promise_names=[], settings=null, func) { ...@@ -39,13 +39,12 @@ mock.initConverse = function (promise_names=[], settings=null, func) {
}; };
window.addEventListener('converse-loaded', () => { window.addEventListener('converse-loaded', () => {
const { _, u, sizzle, Strophe, dayjs, $iq, $msg, $pres } = converse.env; const { u, sizzle, Strophe, dayjs, $iq, $msg, $pres } = converse.env;
mock.waitUntilDiscoConfirmed = async function (_converse, entity_jid, identities, features=[], items=[], type='info') { mock.waitUntilDiscoConfirmed = async function (_converse, entity_jid, identities, features=[], items=[], type='info') {
const iq = await u.waitUntil(() => { const iq = await u.waitUntil(() => {
return _.filter( return _converse.connection.IQ_stanzas.filter(
_converse.connection.IQ_stanzas, iq => sizzle(`iq[to="${entity_jid}"] query[xmlns="http://jabber.org/protocol/disco#${type}"]`, iq).length
(iq) => sizzle(`iq[to="${entity_jid}"] query[xmlns="http://jabber.org/protocol/disco#${type}"]`, iq).length
).pop(); ).pop();
}, 300); }, 300);
const stanza = $iq({ const stanza = $iq({
...@@ -55,15 +54,9 @@ window.addEventListener('converse-loaded', () => { ...@@ -55,15 +54,9 @@ window.addEventListener('converse-loaded', () => {
'id': iq.getAttribute('id'), 'id': iq.getAttribute('id'),
}).c('query', {'xmlns': 'http://jabber.org/protocol/disco#'+type}); }).c('query', {'xmlns': 'http://jabber.org/protocol/disco#'+type});
_.forEach(identities, function (identity) { identities?.forEach(identity => stanza.c('identity', {'category': identity.category, 'type': identity.type}).up());
stanza.c('identity', {'category': identity.category, 'type': identity.type}).up() features?.forEach(feature => stanza.c('feature', {'var': feature}).up());
}); items?.forEach(item => stanza.c('item', {'jid': item}).up());
_.forEach(features, function (feature) {
stanza.c('feature', {'var': feature}).up();
});
_.forEach(items, function (item) {
stanza.c('item', {'jid': item}).up();
});
_converse.connection._dataRecv(mock.createRequest(stanza)); _converse.connection._dataRecv(mock.createRequest(stanza));
} }
...@@ -99,9 +92,7 @@ window.addEventListener('converse-loaded', () => { ...@@ -99,9 +92,7 @@ window.addEventListener('converse-loaded', () => {
const controlbox = document.querySelector("#controlbox"); const controlbox = document.querySelector("#controlbox");
if (u.isVisible(controlbox)) { if (u.isVisible(controlbox)) {
const button = controlbox.querySelector(".close-chatbox-button"); const button = controlbox.querySelector(".close-chatbox-button");
if (!_.isNull(button)) { (button !== null) && button.click();
button.click();
}
} }
return this; return this;
}; };
...@@ -239,9 +230,8 @@ window.addEventListener('converse-loaded', () => { ...@@ -239,9 +230,8 @@ window.addEventListener('converse-loaded', () => {
const stanzas = _converse.connection.IQ_stanzas; const stanzas = _converse.connection.IQ_stanzas;
if (affiliations.includes('member')) { if (affiliations.includes('member')) {
const member_IQ = await u.waitUntil(() => _.filter( const member_IQ = await u.waitUntil(() =>
stanzas, stanzas.filter(s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="member"]`, s).length
s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="member"]`, s).length
).pop()); ).pop());
const member_list_stanza = $iq({ const member_list_stanza = $iq({
'from': 'coven@chat.shakespeare.lit', 'from': 'coven@chat.shakespeare.lit',
...@@ -260,8 +250,7 @@ window.addEventListener('converse-loaded', () => { ...@@ -260,8 +250,7 @@ window.addEventListener('converse-loaded', () => {
} }
if (affiliations.includes('admin')) { if (affiliations.includes('admin')) {
const admin_IQ = await u.waitUntil(() => _.filter( const admin_IQ = await u.waitUntil(() => stanzas.filter(
stanzas,
s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="admin"]`, s).length s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="admin"]`, s).length
).pop()); ).pop());
const admin_list_stanza = $iq({ const admin_list_stanza = $iq({
...@@ -281,8 +270,7 @@ window.addEventListener('converse-loaded', () => { ...@@ -281,8 +270,7 @@ window.addEventListener('converse-loaded', () => {
} }
if (affiliations.includes('owner')) { if (affiliations.includes('owner')) {
const owner_IQ = await u.waitUntil(() => _.filter( const owner_IQ = await u.waitUntil(() => stanzas.filter(
stanzas,
s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="owner"]`, s).length s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="owner"]`, s).length
).pop()); ).pop());
const owner_list_stanza = $iq({ const owner_list_stanza = $iq({
...@@ -452,7 +440,7 @@ window.addEventListener('converse-loaded', () => { ...@@ -452,7 +440,7 @@ window.addEventListener('converse-loaded', () => {
view.el.querySelector('.chat-textarea').value = message; view.el.querySelector('.chat-textarea').value = message;
view.onKeyDown({ view.onKeyDown({
target: view.el.querySelector('textarea.chat-textarea'), target: view.el.querySelector('textarea.chat-textarea'),
preventDefault: _.noop, preventDefault: () => {},
keyCode: 13 keyCode: 13
}); });
return promise; return promise;
...@@ -652,7 +640,7 @@ window.addEventListener('converse-loaded', () => { ...@@ -652,7 +640,7 @@ window.addEventListener('converse-loaded', () => {
_converse.api.vcard.get = function (model, force) { _converse.api.vcard.get = function (model, force) {
let jid; let jid;
if (_.isString(model)) { if (typeof model === 'string' || model instanceof String) {
jid = model; jid = model;
} else if (!model.get('vcard_updated') || force) { } else if (!model.get('vcard_updated') || force) {
jid = model.get('jid') || model.get('muc_jid'); jid = model.get('jid') || model.get('muc_jid');
...@@ -671,15 +659,15 @@ window.addEventListener('converse-loaded', () => { ...@@ -671,15 +659,15 @@ window.addEventListener('converse-loaded', () => {
const vcard = $iq().c('vCard').c('FN').t(fullname).nodeTree; const vcard = $iq().c('vCard').c('FN').t(fullname).nodeTree;
return { return {
'vcard': vcard, 'vcard': vcard,
'fullname': _.get(vcard.querySelector('FN'), 'textContent'), 'fullname': vcard.querySelector('FN')?.textContent,
'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'), 'image': vcard.querySelector('PHOTO BINVAL')?.textContent,
'image_type': _.get(vcard.querySelector('PHOTO TYPE'), 'textContent'), 'image_type': vcard.querySelector('PHOTO TYPE')?.textContent,
'url': _.get(vcard.querySelector('URL'), 'textContent'), 'url': vcard.querySelector('URL')?.textContent,
'vcard_updated': dayjs().format(), 'vcard_updated': dayjs().format(),
'vcard_error': undefined 'vcard_error': undefined
}; };
}; };
if (_.get(settings, 'auto_login') !== false) { if (settings?.auto_login !== false) {
_converse.api.user.login('romeo@montague.lit/orchard', 'secret'); _converse.api.user.login('romeo@montague.lit/orchard', 'secret');
await _converse.api.waitUntil('afterResourceBinding'); await _converse.api.waitUntil('afterResourceBinding');
} }
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
* @license Mozilla Public License (MPLv2) * @license Mozilla Public License (MPLv2)
*/ */
import _ from './lodash.noconflict';
/* START: Removable components /* START: Removable components
* -------------------- * --------------------
* Any of the following components may be removed if they're not needed. * Any of the following components may be removed if they're not needed.
...@@ -59,6 +61,20 @@ const WHITELISTED_PLUGINS = [ ...@@ -59,6 +61,20 @@ const WHITELISTED_PLUGINS = [
'converse-singleton' 'converse-singleton'
]; ];
// Use Mustache style syntax for variable interpolation
/* Configuration of Lodash templates (this config is distinct to the
* config of requirejs-tpl in main.js). This one is for normal inline templates.
*/
_.templateSettings = {
'escape': /\{\{\{([\s\S]+?)\}\}\}/g,
'evaluate': /\{\[([\s\S]+?)\]\}/g,
'interpolate': /\{\{([\s\S]+?)\}\}/g,
'imports': { '_': _ }
};
converse.env._ = _;
const initialize = converse.initialize; const initialize = converse.initialize;
converse.initialize = function (settings, callback) { converse.initialize = function (settings, callback) {
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
import './polyfill'; import './polyfill';
import 'strophe.js/src/websocket'; import 'strophe.js/src/websocket';
import Storage from '@converse/skeletor/src/storage.js'; import Storage from '@converse/skeletor/src/storage.js';
import _ from './lodash.noconflict';
import advancedFormat from 'dayjs/plugin/advancedFormat'; import advancedFormat from 'dayjs/plugin/advancedFormat';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import log from '@converse/headless/log'; import log from '@converse/headless/log';
...@@ -55,18 +54,6 @@ Strophe.addNamespace('VCARD', 'vcard-temp'); ...@@ -55,18 +54,6 @@ Strophe.addNamespace('VCARD', 'vcard-temp');
Strophe.addNamespace('VCARDUPDATE', 'vcard-temp:x:update'); Strophe.addNamespace('VCARDUPDATE', 'vcard-temp:x:update');
Strophe.addNamespace('XFORM', 'jabber:x:data'); Strophe.addNamespace('XFORM', 'jabber:x:data');
// Use Mustache style syntax for variable interpolation
/* Configuration of Lodash templates (this config is distinct to the
* config of requirejs-tpl in main.js). This one is for normal inline templates.
*/
_.templateSettings = {
'escape': /\{\{\{([\s\S]+?)\}\}\}/g,
'evaluate': /\{\[([\s\S]+?)\]\}/g,
'interpolate': /\{\{([\s\S]+?)\}\}/g,
'imports': { '_': _ }
};
/** /**
* Custom error for indicating timeouts * Custom error for indicating timeouts
* @namespace _converse * @namespace _converse
...@@ -1641,7 +1628,6 @@ Object.assign(converse, { ...@@ -1641,7 +1628,6 @@ Object.assign(converse, {
Model, Model,
Promise, Promise,
Strophe, Strophe,
_,
dayjs, dayjs,
html, html,
log, log,
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
*/ */
import "./converse-status"; import "./converse-status";
import log from "@converse/headless/log"; import log from "@converse/headless/log";
import tpl_vcard from "./templates/vcard.html";
import { Collection } from "@converse/skeletor/src/collection"; import { Collection } from "@converse/skeletor/src/collection";
import { Model } from '@converse/skeletor/src/model.js'; import { Model } from '@converse/skeletor/src/model.js';
import { _converse, api, converse } from "./converse-core"; import { _converse, api, converse } from "./converse-core";
...@@ -294,7 +293,19 @@ converse.plugins.add('converse-vcard', { ...@@ -294,7 +293,19 @@ converse.plugins.add('converse-vcard', {
if (!jid) { if (!jid) {
throw Error("No jid provided for the VCard data"); throw Error("No jid provided for the VCard data");
} }
const vcard_el = Strophe.xmlHtmlNode(tpl_vcard(data)).firstElementChild; const div = document.createElement('div');
const vcard_el = u.toStanza(`
<vCard xmlns="vcard-temp">
<FN>${data.fn}</FN>
<NICKNAME>${data.nickname}</NICKNAME>
<URL>${data.url}</URL>
<ROLE>${data.role}</ROLE>
<EMAIL><INTERNET/><PREF/><USERID>${data.email}</USERID></EMAIL>
<PHOTO>
<TYPE>${data.image_type}</TYPE>
<BINVAL>${data.image}</BINVAL>
</PHOTO>
</vCard>`, div);
let result; let result;
try { try {
result = await api.sendIQ(createStanza("set", jid, vcard_el)); result = await api.sendIQ(createStanza("set", jid, vcard_el));
......
...@@ -4,15 +4,6 @@ ...@@ -4,15 +4,6 @@
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"@converse/skeletor": {
"version": "github:conversejs/skeletor#b260c554f4ce961c29deea4740083e58a489aa9b",
"from": "github:conversejs/skeletor#b260c554f4ce961c29deea4740083e58a489aa9b",
"dev": true,
"requires": {
"lit-html": "^1.2.1",
"lodash-es": "^4.17.14"
}
},
"abab": { "abab": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
...@@ -41,9 +32,9 @@ ...@@ -41,9 +32,9 @@
} }
}, },
"lit-html": { "lit-html": {
"version": "1.2.1", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.2.1.tgz", "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.3.0.tgz",
"integrity": "sha512-GSJHHXMGLZDzTRq59IUfL9FCdAlGfqNp/dEa7k7aBaaWD+JKaCjsAk9KYm2V12ItonVaYx2dprN66Zdm1AuBTQ==", "integrity": "sha512-0Q1bwmaFH9O14vycPHw8C/IeHMk/uSDldVLIefu/kfbTBGIc44KGH6A8p1bDfxUfHdc8q6Ct7kQklWoHgr4t1Q==",
"dev": true "dev": true
}, },
"localforage": { "localforage": {
......
<field var="{{{o.name}}}">
{[ if (o.value.constructor === Array) { ]}
{[ o.value.forEach(function (arrayValue) { ]}<value>{{{arrayValue}}}</value>{[ }); ]}
{[ } else { ]}
<value>{{{o.value}}}</value>
{[ } ]}</field>
<vCard xmlns="vcard-temp">
<FN>{{{o.fn}}}</FN>
<NICKNAME>{{{o.nickname}}}</NICKNAME>
<URL>{{{o.url}}}</URL>
<ROLE>{{{o.role}}}</ROLE>
<EMAIL><INTERNET/><PREF/><USERID>{{{o.email}}}</USERID></EMAIL>
<PHOTO>
<TYPE>{{{o.image_type}}}</TYPE>
<BINVAL>{{{o.image}}}</BINVAL>
</PHOTO>
</vCard>
...@@ -193,7 +193,7 @@ u.isServiceUnavailableError = function (stanza) { ...@@ -193,7 +193,7 @@ u.isServiceUnavailableError = function (stanza) {
/** /**
* Merge the second object into the first one. * Merge the second object into the first one.
* @private * @private
* @method u#stringToNode * @method u#merge
* @param { Object } first * @param { Object } first
* @param { Object } second * @param { Object } second
*/ */
...@@ -207,20 +207,6 @@ u.merge = function merge (first, second) { ...@@ -207,20 +207,6 @@ u.merge = function merge (first, second) {
} }
}; };
/**
* Converts an HTML string into a DOM Node.
* Expects that the HTML string has only one top-level element,
* i.e. not multiple ones.
* @private
* @method u#stringToNode
* @param { String } s - The HTML string
*/
u.stringToNode = function (s) {
var div = document.createElement('div');
div.innerHTML = s;
return div.firstElementChild;
};
u.getOuterWidth = function (el, include_margin=false) { u.getOuterWidth = function (el, include_margin=false) {
let width = el.offsetWidth; let width = el.offsetWidth;
if (!include_margin) { if (!include_margin) {
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
* @license Mozilla Public License (MPLv2) * @license Mozilla Public License (MPLv2)
* @description This is the form utilities module. * @description This is the form utilities module.
*/ */
import tpl_field from "../templates/field.html";
import u from "./core"; import u from "./core";
/** /**
...@@ -27,6 +26,11 @@ u.webForm2xForm = function (field) { ...@@ -27,6 +26,11 @@ u.webForm2xForm = function (field) {
} else { } else {
value = field.value; value = field.value;
} }
return u.stringToNode(tpl_field({ name, value })); return u.toStanza(`
<field var="${name}">
${ value.constructor === Array ?
value.map(v => `<value>${v}</value>`) :
`<value>${value}</value>` }
</field>`);
}; };
export default u; export default u;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment