withLoginOverlay.js

From disqus.com, 8 Months ago, written in JavaScript, viewed 3 times. This paste is a reply to Re: withReactSubviews.js from disqus.com - go back
URL https://pastebin.freepbx.org/view/a31514f1/diff Embed
Viewing differences between Re: withReactSubviews.js and withLoginOverlay.js
define('home/mixins/withReactSubviews',[
define('home/mixins/withLoginOverlay',[
    'jquery',
    'underscore',
    'backbone-marionette',

    'home/models/Session',
    'home/views/LoginOverlayView',
    'home/templates/signUpAsideModule',
    'home/utils/layoutUtils',
], function (
    _
$,
    _,
    Marionette,

    Session,
    LoginOverlayView,
    signUpAsideModuleTemplate,
    layoutUtils
) {
    'use strict';

    // Shared modules, only need to be required once\r\n    var React, ReactDOM;\r\n    var sharedModules = {};  // path to imported module\r\n\r\n    /**
     * Called once a module has been fetched. Saves Adds login overlay support to the module
     * for future uses, stores it in 
view to which the component for future
     * rendering, and calls any onFetch callbacks that have
     * been saved on this component.
mixin is applied.
     *
     * @param  {function} module - The fetched If View's template has defined a region for it, renders the log in module
     * @param  {Object} component - The component in the region which has the ability to expand the login overlay.
     *
     * Adds a login footer which shows if the signUpAsideModule is not in
     * the viewport.
     *
     * Handles all the click events 
for this view/module
the footer and signUpAsideModule
     * to show the overlay when appropriate.
     *
     * Overlay itself is a view which handles authentication.
     *
     *
     * Expects to be applied to a Marionette View using the withSubviews mixin,
     * or a Marionette Layout.
     * Can be passed a prompt, which is the message shown to the user above the
     * log in options. If not given, will use a default message.
     */
    var handleOnFetch LoginOverlayMixin function (module, component) {
        sharedModules[component.path] = module;
        component.module = module;
        component.fetching = false;

        _.each(component.onFetch, 
regions: {
            loginModuleRegion: '[data-role=sign-up-module]',
        },

        events: {
            'click [data-action~=show-login-overlay]': 'showLoginOverlay',
        },

        initialize: 
function (fn) (_initialize, options) {
            _initialize.call(this, options);
            this.boundEnsureLoginPromptInViewport = _.bind(this.ensureLoginPromptInViewport, this);
            $(window).scroll(this.boundEnsureLoginPromptInViewport);
        },

        onClose: function () {
            this.unbindScrollHandler();
            if (this.loginOverlayView)
                this.loginOverlayView.close();
        },

        onRender: function (_onRender) 
{
            if (fn)
                fn();
        });
    };

    /**
     * Called once a component has been rendered into the DOM
     * and we have a reference to it. Saves the ref for future
     * component prop updates and calls on onRef callbacks that
     * have been saved on this component.
     *
     * @param {ReactElement} ref - The ReactElement that has
     *                               been rendered into the DOM
     * @param  {Object} component - The component for this view/module
     */
    
(_.isFunction(_onRender))
                _onRender.call(this);

            
var handleRef createLoginModuleView = function (ref, component) {
        component.ref = ref;

        _.each(component.onRef, function (fn) {
            fn.call(component.ref);
        });
    };

    /**
     * Lazy fetches react modules and react libraries. Tries to use
     * previous imports if module has been imported before, and
     * prevents multiple fetches from kicking off at once.
     *
     * @param  {Object}   component - The component whose module to fetch
     * @param  {function} [callback] - A callback to call once the module
     *                                 has been fetched/retrieved
     */
    var loadModule = function (component, callback) {
        component.onFetch.push(callback);

        if (sharedModules[component.path]) {
            handleOnFetch(sharedModules[component.path], component);
            return;
        }

        if (component.fetching)
            return;

        component.fetching = true;

        // Require subview before react libraries because in production
        // the libraries are bundled into the subview file and are not
        // available to load until the subview file has been loaded.
        require([
            component.path,
        ], function (Module) {
            if (!React || !ReactDOM) 
() {
                require([
                    'react',
                    'react-dom',
                ], function (
                    iReact,
                    iReactDOM
                ) {
                    React = iReact;
                    ReactDOM = iReactDOM;

                    handleOnFetch(Module, component);
return new Marionette.ItemView({
                    template: signUpAsideModuleTemplate,
                });
            } else {
                handleOnFetch(Module, component);
            }
        });
    };

    /**
     * Mixin takes in a list of react modules that may be rendered by this view.
     * Each module is specified by a path which will be used to reference it during
     * render or updating the props for that subview.
     *
     * Rendering a react subview will automatically import the subview module
     * and react libraries.
     *
     * @param  {string[]} modules - The list of module paths
     */
    var 
};

            // Allow 
mixin = function (modules) {
        
to work with either Marionette Layouts or with a View
            // with the withSubviews mixin.
            if (this.activateRegion)
                
this.initialize = _.wrap(this.initialize, function (_initialize) {
            _initialize.apply(this, _.rest(arguments));

            // Since we map components by path, this view can only have 1
            // instance of a component as a subview. Can change the mapping
            // if need be.
            
activateRegion(this.loginModuleRegion, createLoginModuleView);
            else
                
this._components = _.chain(modules)
                .map(function (path) {
                    return [path, {
                        path: path,
                        onFetch: [],
                        onRef: [],
                    }];
                })
                .object()
                .value();
        });

loginModuleRegion.show(createLoginModuleView());
        },

        /**
         * Renders Ensures there is a login prompt in the specified react component with viewport. Shows the given props into
         
footer
         
the given element. Fetches prompt iff the module and react libraries if
         * necessary.
         *
         * @param  {string}   path - The path to fetch 
is not in the module.
         * @param  {Object}   props - The initial props to pass to the
         *                            component.
         * @param  {DOMElement}   el - The element into which to render
         *                             the component.
         * @param  {function} [callback] - A function that will be called
         *                                 once the component exists in
         *                                 the DOM.
viewport.
         */
        this.renderReactSubview = function (path, props, el, callback) ensureLoginPromptInViewport: _.debounce(function () {
            var component loginPromptModule = this._components[path];
            
$('[data-role=login-prompt-module]');
            var showFooter = !loginPromptModule.length || !layoutUtils.isElementInViewport(loginPromptModule);
            this.showLoginFooter(showFooter);
        }, 200),

        unbindScrollHandler: function () {
            $(window).off('scroll', this.boundEnsureLoginPromptInViewport);
        },

        showLoginOverlay: function () {
            this.loginOverlayView.showAsOverlay();
        },

        showLoginFooter: function (shouldShow) {
            this.loginOverlayView.showAsFooter(shouldShow);
        },

        onDomRefresh: function (overlayViewOptions, _onDomRefresh) {
            
if (!component)
(_.isFunction(_onDomRefresh))
                _onDomRefresh.call(this);

            // Since the LoginOverlayView is inserted after this view's element,
            // don't need to readd/rerender it when this view is rerendered, as
            // it won't be removed. One initialization is enough.
            if (this.loginOverlayView)
                return;

            if (!component.module) {
                loadModule(component, _.bind(this.renderReactSubview, this, path, props, el, callback));
                return;
            }

            var ref = ReactDOM.render(
                React.createElement(React.createClass({
                    displayName: 'wrapper',
                    getInitialState: function () {
                        return props;
                    },
                    render: function () {
                        
// Wrap component in an element with data-view-type=react. This is used to prevent
                        // 
Add the global backbone anchor click handler from reloading when the clicks come
                        // from a react page.
                        return React.createElement('div', { 'data-view-type': 'react' },
                            React.createElement(component.module, this.state)
                        );
                    },
                })),
                el,
                callback
            );

            handleRef(ref, component);
        };

        /**
         * Updates the set of props given 
overlay view to the component specified DOM. It'll be hidden by the
         * given path. Expects the component to have been rendered via
         * renderReactSubview previously, even if the module fetching/
         * rendering is not yet complete.
         *
         * @param  {string} path - The path of the module which maps to a
         *                         previously rendered component.
         * @param  {Object} props - The new props to pass to the rendered
         *                          component
         */
        
default
            // and shown later by scroll or click events.
            
this.updateComponentProps loginOverlayView function (path, props) {
            var component = 
new LoginOverlayView(overlayViewOptions);
            
this._components[path];
            if (!component)
                return;

            if (!component.ref) {
                component.onRef.push(function () {
                    component.ref.setState(props);
                });
                return;
            }

            component.ref.setState(props);
        };
listenTo(this.loginOverlayView, 'shown:overlay', this.unbindScrollHandler);
            this.$el.after(this.loginOverlayView.render().$el);
        },
    };

    // Used only for testing
    mixin.forget = 
/**
     * @param  {string} prompt - (optional) The message shown to the user above the log in prompt.
     */
    return 
function () (prompt) {
        sharedModules // Mixin only applies on logged out pages
        if (!Session.isKnownToBeLoggedOut())
            return;

        this.regions 
{};
        React 
_.extend({}, LoginOverlayMixin.regions, this.regions);

        this.events 
undefined;
        ReactDOM 
_.extend({}, LoginOverlayMixin.events, this.events);

        this.initialize 
undefined;
    };

    return mixin;
});

_.wrap(this.initialize, LoginOverlayMixin.initialize);

        this.onRender = _.wrap(this.onRender, LoginOverlayMixin.onRender);

        this.onDomRefresh = _.wrap(this.onDomRefresh, _.partial(LoginOverlayMixin.onDomRefresh, { prompt: prompt }));

        _.extend(this, _.pick(LoginOverlayMixin, [
            'showLoginFooter',
            'showLoginOverlay',
            'ensureLoginPromptInViewport',
            'unbindScrollHandler',
        ]));
    };
});


















// https://c.disquscdn.com/next/82c6de3/home/js/mixins/withReactSubviews.com/next/82c6de3/home/js/mixins/withLoginOverlay.js

Replies to withLoginOverlay.js rss

Title Name Language When
BaseSettings.js disqus.com javascript 8 Months ago.

Reply to "withLoginOverlay.js"

Here you can reply to the paste above