Fixes #2939
Data forms with a field named "username" are not displayed #2939 Also adds a test case for ad-hoc commands Update to Lit 2.4.0
This commit is contained in:
parent
83351fb98f
commit
21c41f9265
|
@ -19,6 +19,7 @@
|
|||
- #2879: Quotes, lines not aligned to the first line
|
||||
- #2925: Fix missing disco-items in browser storage.
|
||||
- #2936: Fix documentation about enable_smacks option, which is true by default.
|
||||
- #2939: Data forms with a field named "username" are not displayed
|
||||
- #3005: Fix MUC messages with a fallback body not rendering.
|
||||
- #3007: Fix links becoming text when a message is edited
|
||||
- #3018: Fix MUC icons not functioning.
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"favico.js-slevomat": "^0.3.11",
|
||||
"filesize": "^7.0.0",
|
||||
"jed": "1.1.1",
|
||||
"lit": "^2.2.6",
|
||||
"lit": "^2.4.0",
|
||||
"localforage-webextensionstorage-driver": "^3.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"pluggable.js": "3.0.1",
|
||||
|
@ -3712,9 +3712,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@lit/reactive-element": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.4.tgz",
|
||||
"integrity": "sha512-I1wz4uxOA52zSBhKmv4KQWLJpCyvfpnDg+eQR6mjpRgV+Ldi14HLPpSUpJklZRldz0fFmGCC/kVmuc/3cPFqCg=="
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.4.1.tgz",
|
||||
"integrity": "sha512-qDv4851VFSaBWzpS02cXHclo40jsbAjRXnebNXpm0uVg32kCneZPo9RYVQtrTNICtZ+1wAYHu1ZtxWSWMbKrBw=="
|
||||
},
|
||||
"node_modules/@nicolo-ribaudo/chokidar-2": {
|
||||
"version": "2.1.8-no-fsevents.3",
|
||||
|
@ -10909,13 +10909,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lit": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.2.8.tgz",
|
||||
"integrity": "sha512-QjeNbi/H9LVIHR+u0OqsL+hs62a16m02JlJHYN48HcBuXyiPYR8JvzsTp5dYYS81l+b9Emp3UaGo82EheV0pog==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.4.0.tgz",
|
||||
"integrity": "sha512-fdgzxEtLrZFQU/BqTtxFQCLwlZd9bdat+ltzSFjvWkZrs7eBmeX0L5MHUMb3kYIkuS8Xlfnii/iI5klirF8/Xg==",
|
||||
"dependencies": {
|
||||
"@lit/reactive-element": "^1.3.0",
|
||||
"@lit/reactive-element": "^1.4.0",
|
||||
"lit-element": "^3.2.0",
|
||||
"lit-html": "^2.2.0"
|
||||
"lit-html": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lit-element": {
|
||||
|
@ -10928,9 +10928,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lit-html": {
|
||||
"version": "2.2.7",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.7.tgz",
|
||||
"integrity": "sha512-JhqiAwO1l03kRe68uBZ0i2x4ef2S5szY9vvP411nlrFZIpKK4/hwnhA/15bqbvxe1lV3ipBdhaOzHmyOk7QIRg==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.4.0.tgz",
|
||||
"integrity": "sha512-G6qXu4JNUpY6aaF2VMfaszhO9hlWw0hOTRFDmuMheg/nDYGB+2RztUSOyrzALAbr8Nh0Y7qjhYkReh3rPnplVg==",
|
||||
"dependencies": {
|
||||
"@types/trusted-types": "^2.0.2"
|
||||
}
|
||||
|
@ -20548,9 +20548,9 @@
|
|||
}
|
||||
},
|
||||
"@lit/reactive-element": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.4.tgz",
|
||||
"integrity": "sha512-I1wz4uxOA52zSBhKmv4KQWLJpCyvfpnDg+eQR6mjpRgV+Ldi14HLPpSUpJklZRldz0fFmGCC/kVmuc/3cPFqCg=="
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.4.1.tgz",
|
||||
"integrity": "sha512-qDv4851VFSaBWzpS02cXHclo40jsbAjRXnebNXpm0uVg32kCneZPo9RYVQtrTNICtZ+1wAYHu1ZtxWSWMbKrBw=="
|
||||
},
|
||||
"@nicolo-ribaudo/chokidar-2": {
|
||||
"version": "2.1.8-no-fsevents.3",
|
||||
|
@ -26097,13 +26097,13 @@
|
|||
}
|
||||
},
|
||||
"lit": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.2.8.tgz",
|
||||
"integrity": "sha512-QjeNbi/H9LVIHR+u0OqsL+hs62a16m02JlJHYN48HcBuXyiPYR8JvzsTp5dYYS81l+b9Emp3UaGo82EheV0pog==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.4.0.tgz",
|
||||
"integrity": "sha512-fdgzxEtLrZFQU/BqTtxFQCLwlZd9bdat+ltzSFjvWkZrs7eBmeX0L5MHUMb3kYIkuS8Xlfnii/iI5klirF8/Xg==",
|
||||
"requires": {
|
||||
"@lit/reactive-element": "^1.3.0",
|
||||
"@lit/reactive-element": "^1.4.0",
|
||||
"lit-element": "^3.2.0",
|
||||
"lit-html": "^2.2.0"
|
||||
"lit-html": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"lit-element": {
|
||||
|
@ -26116,9 +26116,9 @@
|
|||
}
|
||||
},
|
||||
"lit-html": {
|
||||
"version": "2.2.7",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.7.tgz",
|
||||
"integrity": "sha512-JhqiAwO1l03kRe68uBZ0i2x4ef2S5szY9vvP411nlrFZIpKK4/hwnhA/15bqbvxe1lV3ipBdhaOzHmyOk7QIRg==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.4.0.tgz",
|
||||
"integrity": "sha512-G6qXu4JNUpY6aaF2VMfaszhO9hlWw0hOTRFDmuMheg/nDYGB+2RztUSOyrzALAbr8Nh0Y7qjhYkReh3rPnplVg==",
|
||||
"requires": {
|
||||
"@types/trusted-types": "^2.0.2"
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
"dompurify": "^2.3.1",
|
||||
"favico.js-slevomat": "^0.3.11",
|
||||
"jed": "1.1.1",
|
||||
"lit": "^2.2.6"
|
||||
"lit": "^2.4.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"autoprefixer": "10.4.5"
|
||||
|
|
|
@ -85,6 +85,7 @@ export default class AdHocCommands extends CustomElement {
|
|||
|
||||
hideCommandForm (ev) {
|
||||
ev.preventDefault();
|
||||
this.nonce = u.getUniqueId();
|
||||
this.showform = ''
|
||||
}
|
||||
|
||||
|
@ -117,7 +118,9 @@ export default class AdHocCommands extends CustomElement {
|
|||
result = await api.sendIQ(iq);
|
||||
} catch (e) {
|
||||
cmd.alert_type = 'danger';
|
||||
cmd.alert = __('Sorry, an error occurred while trying to execute the command. See the developer console for details');
|
||||
cmd.alert = __(
|
||||
'Sorry, an error occurred while trying to execute the command. See the developer console for details'
|
||||
);
|
||||
log.error('Error while trying to execute an ad-hoc command');
|
||||
log.error(e);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ export default (o, command) => {
|
|||
const i18n_hide = __('Hide');
|
||||
const i18n_run = __('Execute');
|
||||
return html`
|
||||
<span> <!-- Don't remove this <span>,
|
||||
this is a workaround for a lit bug where a <form> cannot be removed
|
||||
if it contains an <input> with name "remove" -->
|
||||
<form @submit=${o.runCommand}>
|
||||
${ command.alert ? html`<div class="alert alert-${command.alert_type}" role="alert">${command.alert}</div>` : '' }
|
||||
<fieldset class="form-group">
|
||||
|
@ -19,5 +22,6 @@ export default (o, command) => {
|
|||
<input type="button" class="btn btn-secondary button-cancel" value="${i18n_hide}" @click=${o.hideCommandForm}>
|
||||
</fieldset>
|
||||
</form>
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/*global mock, converse */
|
||||
|
||||
const { sizzle, u, stx } = converse.env;
|
||||
const { Strophe, sizzle, u, stx } = converse.env;
|
||||
|
||||
describe("Ad-hoc commands", function () {
|
||||
|
||||
fit("can be queried for via a modal", mock.initConverse([], {}, async (_converse) => {
|
||||
it("can be queried for via a modal", mock.initConverse([], {}, async (_converse) => {
|
||||
const { api } = _converse;
|
||||
const entity_jid = 'muc.montague.lit';
|
||||
const { IQ_stanzas } = _converse.connection;
|
||||
|
||||
const modal = await api.modal.show('converse-user-settings-modal');
|
||||
await u.waitUntil(() => u.isVisible(modal));
|
||||
|
@ -23,8 +24,8 @@ describe("Ad-hoc commands", function () {
|
|||
|
||||
await mock.waitUntilDiscoConfirmed(_converse, entity_jid, [], ['http://jabber.org/protocol/commands'], [], 'info');
|
||||
|
||||
const sel = `iq[to="${entity_jid}"] query[xmlns="http://jabber.org/protocol/disco#items"]`;
|
||||
const iq = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(iq => sizzle(sel, iq).length).pop());
|
||||
let sel = `iq[to="${entity_jid}"] query[xmlns="http://jabber.org/protocol/disco#items"]`;
|
||||
let iq = await u.waitUntil(() => IQ_stanzas.filter(iq => sizzle(sel, iq).length).pop());
|
||||
|
||||
_converse.connection._dataRecv(mock.createRequest(stx`
|
||||
<iq type="result"
|
||||
|
@ -51,6 +52,9 @@ describe("Ad-hoc commands", function () {
|
|||
<item jid="${entity_jid}"
|
||||
node="restart"
|
||||
name="Restart Service"/>
|
||||
<item jid="${entity_jid}"
|
||||
node="adduser"
|
||||
name="Add User"/>
|
||||
</query>
|
||||
</iq>`));
|
||||
|
||||
|
@ -58,12 +62,75 @@ describe("Ad-hoc commands", function () {
|
|||
expect(heading.textContent).toBe('Commands found:');
|
||||
|
||||
const items = adhoc_form.querySelectorAll('.list-group-item:not(.active)');
|
||||
expect(items.length).toBe(6);
|
||||
expect(items.length).toBe(7);
|
||||
expect(items[0].textContent.trim()).toBe('List Service Configurations');
|
||||
expect(items[1].textContent.trim()).toBe('Configure Service');
|
||||
expect(items[2].textContent.trim()).toBe('Reset Service Configuration');
|
||||
expect(items[3].textContent.trim()).toBe('Start Service');
|
||||
expect(items[4].textContent.trim()).toBe('Stop Service');
|
||||
expect(items[5].textContent.trim()).toBe('Restart Service');
|
||||
expect(items[6].textContent.trim()).toBe('Add User');
|
||||
|
||||
items[6].querySelector('a').click();
|
||||
|
||||
sel = `iq[to="${entity_jid}"][type="set"] command`;
|
||||
iq = await u.waitUntil(() => IQ_stanzas.filter(iq => sizzle(sel, iq).length).pop());
|
||||
|
||||
expect(Strophe.serialize(iq)).toBe(
|
||||
`<iq id="${iq.getAttribute("id")}" to="${entity_jid}" type="set" xmlns="jabber:client">`+
|
||||
`<command action="execute" node="adduser" xmlns="http://jabber.org/protocol/commands"/>`+
|
||||
`</iq>`
|
||||
);
|
||||
|
||||
_converse.connection._dataRecv(mock.createRequest(stx`
|
||||
<iq to="${_converse.jid}" xmlns="jabber:client" type="result" xml:lang="en" id="${iq.getAttribute('id')}" from="${entity_jid}">
|
||||
<command status="executing" node="adduser" sessionid="1653988890.6236324-886f3dc54ce443c6b4a1805877bf7faa" xmlns="http://jabber.org/protocol/commands">
|
||||
<actions>
|
||||
<complete />
|
||||
</actions>
|
||||
<x type="form" xmlns="jabber:x:data">
|
||||
<title>Title</title>
|
||||
<instructions>Instructions</instructions>
|
||||
<field type="boolean" label="Remove my registration" var="remove">
|
||||
<value>0</value>
|
||||
<required />
|
||||
</field>
|
||||
<field type="text-single" label="User name" var="username">
|
||||
<value>romeo</value>
|
||||
<required />
|
||||
</field>
|
||||
<field type="text-single" label="Password" var="password">
|
||||
<value>secret</value>
|
||||
<required />
|
||||
</field>
|
||||
</x>
|
||||
</command>
|
||||
</iq>`));
|
||||
|
||||
const form = await u.waitUntil(() => adhoc_form.querySelector('form form'));
|
||||
expect(u.isVisible(form)).toBe(true);
|
||||
const inputs = form.querySelectorAll('input');
|
||||
expect(inputs.length).toBe(7);
|
||||
expect(inputs[0].getAttribute('name')).toBe('command_node');
|
||||
expect(inputs[0].getAttribute('type')).toBe('hidden');
|
||||
expect(inputs[0].getAttribute('value')).toBe('adduser');
|
||||
expect(inputs[1].getAttribute('name')).toBe('command_jid');
|
||||
expect(inputs[0].getAttribute('type')).toBe('hidden');
|
||||
expect(inputs[1].getAttribute('value')).toBe('muc.montague.lit');
|
||||
expect(inputs[2].getAttribute('name')).toBe('remove');
|
||||
expect(inputs[2].getAttribute('type')).toBe('checkbox');
|
||||
expect(inputs[3].getAttribute('name')).toBe('username');
|
||||
expect(inputs[3].getAttribute('type')).toBe('text');
|
||||
expect(inputs[3].getAttribute('value')).toBe('romeo');
|
||||
expect(inputs[4].getAttribute('name')).toBe('password');
|
||||
expect(inputs[4].getAttribute('type')).toBe('password');
|
||||
expect(inputs[4].getAttribute('value')).toBe('secret');
|
||||
expect(inputs[5].getAttribute('type')).toBe('submit');
|
||||
expect(inputs[5].getAttribute('value')).toBe('Execute');
|
||||
expect(inputs[6].getAttribute('type')).toBe('button');
|
||||
expect(inputs[6].getAttribute('value')).toBe('Hide');
|
||||
|
||||
inputs[6].click();
|
||||
await u.waitUntil(() => !u.isVisible(form));
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -20,7 +20,7 @@ export async function fetchCommandForm (command) {
|
|||
command.sessionid = cmd_el.getAttribute('sessionid');
|
||||
command.instructions = sizzle('x[type="form"][xmlns="jabber:x:data"] instructions', cmd_el).pop()?.textContent;
|
||||
command.fields = sizzle('x[type="form"][xmlns="jabber:x:data"] field', cmd_el)
|
||||
.map(f => u.xForm2TemplateResult(f, cmd_el));
|
||||
.map(f => u.xForm2TemplateResult(f, cmd_el, { domain: jid }));
|
||||
|
||||
} catch (e) {
|
||||
if (e === null) {
|
||||
|
|
|
@ -438,7 +438,7 @@ u.fadeIn = function (el, callback) {
|
|||
* @param { Object } options
|
||||
* @returns { TemplateResult }
|
||||
*/
|
||||
u.xForm2TemplateResult = function (field, stanza, options) {
|
||||
u.xForm2TemplateResult = function (field, stanza, options={}) {
|
||||
if (field.getAttribute('type') === 'list-single' || field.getAttribute('type') === 'list-multi') {
|
||||
const values = u.queryChildren(field, 'value').map(el => el?.textContent);
|
||||
const options = u.queryChildren(field, 'option').map(option => {
|
||||
|
@ -474,8 +474,7 @@ u.xForm2TemplateResult = function (field, stanza, options) {
|
|||
'id': u.getUniqueId(),
|
||||
'name': field.getAttribute('var'),
|
||||
'label': field.getAttribute('label') || '',
|
||||
'checked': ((value === '1' || value === 'true') && 'checked="1"') || '',
|
||||
'required': !!field.querySelector('required')
|
||||
'checked': ((value === '1' || value === 'true') && 'checked="1"') || ''
|
||||
});
|
||||
} else if (field.getAttribute('var') === 'url') {
|
||||
return tpl_form_url({
|
||||
|
@ -491,6 +490,14 @@ u.xForm2TemplateResult = function (field, stanza, options) {
|
|||
'value': field.querySelector('value')?.textContent,
|
||||
'required': !!field.querySelector('required')
|
||||
});
|
||||
} else if (field.getAttribute('var') === 'password') {
|
||||
return tpl_form_input({
|
||||
'name': field.getAttribute('var'),
|
||||
'type': 'password',
|
||||
'label': field.getAttribute('label') || '',
|
||||
'value': field.querySelector('value')?.textContent,
|
||||
'required': !!field.querySelector('required')
|
||||
});
|
||||
} else if (field.getAttribute('var') === 'ocr') {
|
||||
// Captcha
|
||||
const uri = field.querySelector('uri');
|
||||
|
|
Loading…
Reference in New Issue