Jelajahi Sumber

register: Use lit-html to render templates

JC Brand 4 tahun lalu
induk
melakukan
9372ad2dff

+ 5 - 0
sass/_core.scss

@@ -109,6 +109,11 @@ body.converse-fullscreen {
         padding: 0 !important;
     }
 
+    .no-scrolling {
+      overflow-x: none;
+      overflow-y: none;
+    }
+
     &.converse-overlayed {
         > .row {
             flex-direction: row-reverse;

+ 1 - 1
spec/register.js

@@ -5,7 +5,7 @@ const $iq = converse.env.$iq;
 const { _, sizzle}  = converse.env;
 const u = converse.env.utils;
 
-describe("The Registration Panel", function () {
+fdescribe("The Registration Panel", function () {
 
     it("is not available unless allow_registration=true",
         mock.initConverse(

+ 33 - 62
src/plugins/register/panel.js

@@ -2,9 +2,7 @@ import log from "@converse/headless/log";
 import tpl_form_input from "templates/form_input.js";
 import tpl_form_url from "templates/form_url.js";
 import tpl_form_username from "templates/form_username.js";
-import tpl_register_panel from "./templates/register_panel.html";
-import tpl_registration_form from "./templates/registration_form.js";
-import tpl_registration_request from "./templates/registration_request.html";
+import tpl_register_panel from "./templates/register_panel.js";
 import tpl_spinner from "templates/spinner.js";
 import utils from "@converse/headless/utils/form";
 import { View } from "@converse/skeletor/src/view";
@@ -18,6 +16,11 @@ const { Strophe, sizzle, $iq } = converse.env;
 const u = converse.env.utils;
 
 
+const CHOOSE_PROVIDER = 0;
+const FETCHING_FORM = 1;
+const REGISTRATION_FORM = 2;
+
+
 /**
  * @class
  * @namespace _converse.RegisterPanel
@@ -35,29 +38,33 @@ const RegisterPanel = View.extend({
     initialize () {
         this.reset();
         api.listen.on('connectionInitialized', () => this.registerHooks());
+        this.listenTo(this.model, 'change:registration_status', this.render);
+
+        const domain = api.settings.get('registration_domain');
+        if (domain) {
+            this.fetchRegistrationForm(domain);
+        } else {
+            this.model.set('registration_status', CHOOSE_PROVIDER);
+        }
     },
 
     render () {
-        this.model.set('registration_form_rendered', false);
-        this.el.innerHTML = tpl_register_panel({
-            '__': __,
-            'default_domain': api.settings.get('registration_domain'),
-            'label_register': __('Fetch registration form'),
-            'help_providers': __('Tip: A list of public XMPP providers is available'),
-            'help_providers_link': __('here'),
-            'href_providers': api.settings.get('providers_link'),
-            'domain_placeholder': api.settings.get('domain_placeholder')
-        });
-        if (api.settings.get('registration_domain')) {
-            this.fetchRegistrationForm(api.settings.get('registration_domain'));
-        }
+        render(tpl_register_panel({
+            'domain': this.domain,
+            'fields': this.fields,
+            'form_fields': this.form_fields,
+            'instructions': this.instructions,
+            'model': this.model,
+            'title': this.title,
+        }), this.el);
         return this;
     },
 
+    /**
+     * Hook into Strophe's _connect_cb, so that we can send an IQ
+     * requesting the registration fields.
+     */
     registerHooks () {
-        /* Hook into Strophe's _connect_cb, so that we can send an IQ
-         * requesting the registration fields.
-         */
         const conn = _converse.connection;
         const connect_cb = conn._connect_cb.bind(conn);
         conn._connect_cb = (req, callback, raw) => {
@@ -136,7 +143,7 @@ const RegisterPanel = View.extend({
             return false;
         }
         this.setFields(stanza);
-        if (!this.model.get('registration_form_rendered')) {
+        if (this.model.get('registration_status') === FETCHING_FORM) {
             this.renderRegistrationForm(stanza);
         }
         return false;
@@ -200,9 +207,7 @@ const RegisterPanel = View.extend({
      * @param { String } domain_name - XMPP server domain
      */
     async fetchRegistrationForm (domain_name) {
-        if (!this.model.get('registration_form_rendered')) {
-            this.renderRegistrationRequest();
-        }
+        this.model.set('registration_status', FETCHING_FORM);
         this.reset({
             'domain': Strophe.getDomainFromJid(domain_name),
             '_registering': true
@@ -214,21 +219,6 @@ const RegisterPanel = View.extend({
         return false;
     },
 
-    /**
-     * Clear the form and inform the user that the registration
-     * form is being fetched.
-     * @private
-     */
-    renderRegistrationRequest () {
-        this.clearRegistrationForm().insertAdjacentHTML(
-            'beforeend',
-            tpl_registration_request({
-                '__': _converse.__,
-                'cancel': api.settings.get('registration_domain'),
-            })
-        );
-    },
-
     giveFeedback (message, klass) {
         let feedback = this.el.querySelector('.reg-feedback');
         if (feedback !== null) {
@@ -243,17 +233,9 @@ const RegisterPanel = View.extend({
         }
     },
 
-    clearRegistrationForm () {
-        const form = this.el.querySelector('form');
-        form.innerHTML = '';
-        this.model.set('registration_form_rendered', false);
-        return form;
-    },
-
     showSpinner () {
         const form = this.el.querySelector('form');
         render(tpl_spinner(), form);
-        this.model.set('registration_form_rendered', false);
         return this;
     },
 
@@ -346,17 +328,8 @@ const RegisterPanel = View.extend({
      * @param { XMLElement } stanza - The IQ stanza received from the XMPP server.
      */
     renderRegistrationForm (stanza) {
-        const form = this.el.querySelector('form');
-        const tpl = tpl_registration_form({
-            'domain': this.domain,
-            'title': this.title,
-            'instructions': this.instructions,
-            'fields': this.fields,
-            'form_fields': this.getFormFields(stanza)
-        });
-        render(tpl, form);
-        form.classList.remove('hidden');
-        this.model.set('registration_form_rendered', true);
+        this.form_fields = this.getFormFields(stanza);
+        this.model.set('registration_status', REGISTRATION_FORM);
     },
 
     showValidationError (message) {
@@ -408,11 +381,9 @@ const RegisterPanel = View.extend({
     abortRegistration () {
         _converse.connection._proto._abortAllRequests();
         _converse.connection.reset();
-        if (this.model.get('registration_form_rendered')) {
-            if (api.settings.get('registration_domain') && this.model.get('registration_form_rendered')) {
-                this.fetchRegistrationForm(
-                    api.settings.get('registration_domain')
-                );
+        if ([FETCHING_FORM, REGISTRATION_FORM].includes(this.model.get('registration_status'))) {
+            if (api.settings.get('registration_domain')) {
+                this.fetchRegistrationForm(api.settings.get('registration_domain'));
             }
         } else {
             this.render();

+ 0 - 26
src/plugins/register/templates/register_panel.html

@@ -1,26 +0,0 @@
-<div>
-    <form id="converse-register" class="converse-form">
-        <legend class="col-form-label">{{{o.__("Create your account")}}}</legend>
-
-        <div class="form-group">
-            <label>{{{o.__("Please enter the XMPP provider to register with:")}}}</label>
-            <div class="form-errors hidden"></div>
-
-            {[ if (o.default_domain) { ]}
-                {{{o.default_domain}}}
-            </div>
-            {[ } else { ]}
-                <input class="form-control" required="required" type="text" name="domain" placeholder="{{{o.domain_placeholder}}}"/>
-                <p class="form-text text-muted">{{{o.help_providers}}} <a href="{{{o.href_providers}}}" class="url" target="_blank" rel="noopener">{{{o.help_providers_link}}}</a>.</p>
-            </div>
-            <fieldset class="buttons">
-                <input class="btn btn-primary" type="submit" value="{{{o.label_register}}}"/>
-                <div class="switch-form">
-                    <p>{{{ o.__("Already have a chat account?") }}}</p>
-                    <p><a class="login-here toggle-register-login" href="#converse/login">{{{o.__("Log in here")}}}</a></p>
-                </div>
-            </fieldset>
-            {[ } ]}
-        <!--</div>-->
-    </form>
-</div>

+ 80 - 0
src/plugins/register/templates/register_panel.js

@@ -0,0 +1,80 @@
+import tpl_registration_form from './registration_form.js';
+import tpl_spinner from 'templates/spinner.js';
+import { __ } from 'i18n';
+import { api } from '@converse/headless/core';
+import { html } from 'lit-html';
+
+const tpl_form_request = () => {
+    const default_domain = api.settings.get('registration_domain');
+    const i18n_fetch_form = __("Hold tight, we're fetching the registration form…");
+    const i18n_cancel = __('Cancel');
+    return html`
+        <form id="converse-register" class="converse-form no-scrolling">
+            ${tpl_spinner({ 'classes': 'hor_centered' })}
+            <p class="info">${i18n_fetch_form}</p>
+            ${default_domain
+                ? ''
+                : html`
+                      <button class="btn btn-secondary button-cancel hor_centered">${i18n_cancel}</button>
+                  `}
+        </form>
+    `;
+};
+
+const tpl_domain_input = () => {
+    const domain_placeholder = api.settings.get('domain_placeholder');
+    const i18n_providers = __('Tip: A list of public XMPP providers is available');
+    const i18n_providers_link = __('here');
+    const href_providers = api.settings.get('providers_link');
+    return html`
+        <input class="form-control" required="required" type="text" name="domain" placeholder="${domain_placeholder}" />
+        <p class="form-text text-muted">
+            ${i18n_providers}
+            <a href="${href_providers}" class="url" target="_blank" rel="noopener">${i18n_providers_link}</a>.
+        </p>
+    `;
+};
+
+const tpl_fetch_form_buttons = () => {
+    const i18n_register = __('Fetch registration form');
+    const i18n_existing_account = __('Already have a chat account?');
+    const i18n_login = __('Log in here');
+    return html`
+        <fieldset class="buttons">
+            <input class="btn btn-primary" type="submit" value="${i18n_register}" />
+            <div class="switch-form">
+                <p>${i18n_existing_account}</p>
+                <p><a class="login-here toggle-register-login" href="#converse/login">${i18n_login}</a></p>
+            </div>
+        </fieldset>
+    `;
+};
+
+const tpl_choose_provider = () => {
+    const default_domain = api.settings.get('registration_domain');
+    const i18n_create_account = __('Create your account');
+    const i18n_choose_provider = __('Please enter the XMPP provider to register with:');
+    return html`
+        <form id="converse-register" class="converse-form">
+            <legend class="col-form-label">${i18n_create_account}</legend>
+            <div class="form-group">
+                <label>${i18n_choose_provider}</label>
+                <div class="form-errors hidden"></div>
+                ${default_domain ? default_domain : tpl_domain_input()}
+            </div>
+            ${default_domain ? '' : tpl_fetch_form_buttons()}
+        </form>
+    `;
+};
+
+const CHOOSE_PROVIDER = 0;
+const FETCHING_FORM = 1;
+const REGISTRATION_FORM = 2;
+
+export default o => {
+    return html`
+        ${o.model.get('registration_status') === CHOOSE_PROVIDER ? tpl_choose_provider() : ''}
+        ${o.model.get('registration_status') === FETCHING_FORM ? tpl_form_request(o) : ''}
+        ${o.model.get('registration_status') === REGISTRATION_FORM ? tpl_registration_form(o) : ''}
+    `;
+};

+ 36 - 21
src/plugins/register/templates/registration_form.js

@@ -1,28 +1,43 @@
 import { __ } from 'i18n';
-import { api } from "@converse/headless/core";
-import { html } from "lit-html";
+import { api } from '@converse/headless/core';
+import { html } from 'lit-html';
 
-export default (o) => {
+export default o => {
     const i18n_choose_provider = __('Choose a different provider');
-    const i18n_has_account = __("Already have a chat account?");
-    const i18n_legend = __("Account Registration:");
-    const i18n_login = __("Log in here");
+    const i18n_has_account = __('Already have a chat account?');
+    const i18n_legend = __('Account Registration:');
+    const i18n_login = __('Log in here');
     const i18n_register = __('Register');
-    const registration_domain = api.settings.get('registration_domain')
+    const registration_domain = api.settings.get('registration_domain');
 
     return html`
-        <legend class="col-form-label">${i18n_legend} ${o.domain}</legend>
-        <p class="title">${o.title}</p>
-        <p class="form-help instructions">${o.instructions}</p>
-        <div class="form-errors hidden"></div>
-        ${ o.form_fields }
+        <form id="converse-register" class="converse-form">
+            <legend class="col-form-label">${i18n_legend} ${o.domain}</legend>
+            <p class="title">${o.title}</p>
+            <p class="form-help instructions">${o.instructions}</p>
+            <div class="form-errors hidden"></div>
+            ${o.form_fields}
 
-        <fieldset class="buttons form-group">
-            ${ o.fields ? html`<input type="submit" class="btn btn-primary" value="${i18n_register}"/>` : '' }
-            ${ registration_domain ? '' : html`<input type="button" class="btn btn-secondary button-cancel" value="${i18n_choose_provider}"/>` }
-            <div class="switch-form">
-                <p>${i18n_has_account}</p>
-                <p><a class="login-here toggle-register-login" href="#converse/login">${i18n_login}</a></p>
-            </div>
-        </fieldset>`;
-}
+            <fieldset class="buttons form-group">
+                ${o.fields
+                    ? html`
+                          <input type="submit" class="btn btn-primary" value="${i18n_register}" />
+                      `
+                    : ''}
+                ${registration_domain
+                    ? ''
+                    : html`
+                          <input
+                              type="button"
+                              class="btn btn-secondary button-cancel"
+                              value="${i18n_choose_provider}"
+                          />
+                      `}
+                <div class="switch-form">
+                    <p>${i18n_has_account}</p>
+                    <p><a class="login-here toggle-register-login" href="#converse/login">${i18n_login}</a></p>
+                </div>
+            </fieldset>
+        </form>
+    `;
+};

+ 0 - 5
src/plugins/register/templates/registration_request.html

@@ -1,5 +0,0 @@
-<span class="spinner login-submit fa fa-spinner"></span>
-<p class="info">{{{o.__("Hold tight, we're fetching the registration form…")}}}</p>
-{[ if (o.cancel) { ]}
-    <button class="btn btn-secondary button-cancel hor_centered">{{{o.__('Cancel')}}}</button>
-{[ } ]}