API Docs for: 1.0.0
Show:

File: Resources/public/js/views/fields/richtext/ez-richtext-resolveembed.js

/*
 * Copyright (C) eZ Systems AS. All rights reserved.
 * For full copyright and license information view LICENSE file distributed with this source code.
 */
YUI.add('ez-richtext-resolveembed', function (Y) {
    "use strict";
    /**
     * Provides the resolve embed richtext processor
     *
     * @module ez-richtext-resolveembed
     */
    Y.namespace('eZ');

    /**
     * The Richtext resolve embed processor
     *
     * @namespace eZ
     * @class RichTextResolveEmbed
     * @constructor
     */
    var ResolveEmbed = function () {
            /**
             * Contains the message to display when the embed Content item could not
             * be loaded.
             *
             * @property _notLoadedMessage
             * @type {String}
             * @protected
             */
            this._notLoadedMessage = Y.eZ.trans('embed.content.not.loaded', {}, 'fieldedit');
        };

    /**
     * Resolves the embed by search for the corresponding content by content id.
     *
     * @method process
     * @param {eZ.FieldView|eZ.FieldEditView} view
     * @param {EventFacade} [event] the event parameters (if any) that triggered
     * the process
     */
    ResolveEmbed.prototype.process = function (view, event) {
        var embeds = this._getEmbedList(view),
            mapNodes = this._buildEmbedMapNodes(embeds);

        if ( event && event.embedStruct ) {
            this._renderSelectedContent(view, event.embedStruct, mapNodes);
        }
        if ( !Y.Object.isEmpty(mapNodes) ) {
            this._renderLoadingEmbedElements(mapNodes);
            this._loadEmbeds(mapNodes, view);
        }
    };

    /**
     * Renders the embed from the embedStruct provided in the event parameters
     * that triggered the process.
     *
     * @method _renderSelectedContent
     * @protected
     * @param {eZ.FieldView|eZ.FieldEditView} view
     * @param {Object} embedStruct
     * @param {Object} mapNodes
     */
    ResolveEmbed.prototype._renderSelectedContent = function (view, embedStruct, mapNodes) {
        var embedNodes = mapNodes[embedStruct.contentInfo.get('contentId')];

        if ( !embedNodes ) {
            return;
        }

        embedNodes.forEach(function (node) {
            this._appendContentNode(node)
                .setContent(embedStruct.contentInfo.get('name'));
        }, this);
        delete mapNodes[embedStruct.contentInfo.get('contentId')];
    };

    /**
     * Returns a node list of nodes representing an embed that are not yet been
     * rendered.
     *
     * @method _getEmbedList
     * @protected
     * @param {eZ.FieldView|eZ.FieldEditView} view
     * @return {Y.NodeList}
     */
    ResolveEmbed.prototype._getEmbedList = function (view) {
        var embeds = view.get('container').all('[data-ezelement="ezembed"]'),
            list = new Y.NodeList();

        embeds.each(function (embed) {
            if ( !this._getEmbedContent(embed) ) {
                list.push(embed);
            }
        }, this);

        return list;
    };

    /**
     * Renders the embeds in the `mapNode` as loading
     *
     * @protected
     * @method _renderLoadingEmbedElements
     * @param {Object} mapNode
     */
    ResolveEmbed.prototype._renderLoadingEmbedElements = function (mapNode) {
        Y.Object.each(mapNode, function (embedNodes) {
            embedNodes.forEach(this._renderLoadingEmbed, this);
        }, this);
    };

    /**
     * Renders the given embed node as loading
     *
     * @protected
     * @method _renderLoadingEmbed
     * @param {Node} node
     */
    ResolveEmbed.prototype._renderLoadingEmbed = function (node) {
        this._setLoading(node);
        this._appendLoadingNode(node);
    };

    /**
     * Renders the embed as in *loading mode*.
     *
     * @method _renderLoadingEmbeds
     * @protected
     * @param {NodeList} embeds
     * @deprecated
     */
    ResolveEmbed.prototype._renderLoadingEmbeds = function (embeds) {
        console.log('[DEPRECATED] _renderLoadingEmbeds is deprecated, it will be removed from PlatformUI 2.0');
        embeds.each(function (embedNode) {
            this._setLoading(embedNode);
            this._appendLoadingNode(embedNode);
        }, this);
    };

    /**
     * Search for the content that are embed
     *
     * @method _loadEmbeds
     * @protected
     * @param {Object} mapNode
     * @param {eZ.FieldView|eZ.FieldEditView} view
     */
    ResolveEmbed.prototype._loadEmbeds = function (mapNode, view) {
        view.fire('contentSearch', {
            viewName: 'resolveembed-field-' + view.get('field').id,
            search: {
                filter: {'ContentIdCriterion': Object.keys(mapNode).join(',')},
                offset: 0,
            },
            callback: Y.bind(this._renderEmbed, this, mapNode),
        });
    };

    /**
     * Renders the embed with the search results
     *
     * @method _renderEmbed
     * @protected
     * @param {Object} mapNode
     * @param {Error|false} error
     * @param {Array} results
     */
    ResolveEmbed.prototype._renderEmbed = function (mapNode, error, results) {
        var localMapNode = Y.merge(mapNode);

        if ( error ) {
            this._renderNotLoadedEmbed(localMapNode);
            return;
        }

        results.forEach(function (struct) {
            var content = struct.content;

            localMapNode[content.get('contentId')].forEach(Y.bind(this._renderEmbedContentNode, this, content));
            delete localMapNode[content.get('contentId')];
        }, this);
        this._renderNotLoadedEmbed(localMapNode);
    };

    /**
     * Renders the content into the embedNode as an embed.
     *
     * @method _renderEmbedContentNode
     * @protected
     * @param {eZ.Content} content
     * @param {Node} embedNode
     */
    ResolveEmbed.prototype._renderEmbedContentNode = function (content, embedNode) {
        this._unsetLoading(embedNode);
        this._getEmbedContent(embedNode).setContent(content.get('name'));
    };

    /**
     * Renders the embed node referenced in mapNode as not loaded.
     *
     * @method _renderNotLoadedEmbed
     * @protected
     * @param {Object} mapNode
     */
    ResolveEmbed.prototype._renderNotLoadedEmbed = function (mapNode) {
        Object.keys(mapNode).forEach(function (missingContentId) {
            mapNode[missingContentId].forEach(function (embedNode) {
                this._unsetLoading(embedNode);
                this._setNotLoaded(embedNode);
            }, this);
        }, this);
    };

    /**
     * Builds a map between the content id and the embed nodes embedding it.
     *
     * @method _buildEmbedMapNodes
     * @private
     * @param {NodeList} embeds
     * @return {Object}
     */
    ResolveEmbed.prototype._buildEmbedMapNodes = function (embeds) {
        var map = {};

        embeds.each(function (embed) {
            var contentId = this._getEmbedContentId(embed);

            map[contentId] = map[contentId] || [];
            map[contentId].push(embed);
        }, this);
        return map;
    };

    /**
     * Returns the content id of an embed node
     *
     * @method _getEmbedContentId
     * @param {Node} embedNode
     * @private
     * @return {String}
     */
    ResolveEmbed.prototype._getEmbedContentId = function (embedNode) {
        return embedNode.getData('href').replace('ezcontent://', '');
    };

    /**
     * Adds the loading class on the embed node
     *
     * @method _setLoading
     * @protected
     * @param {Node} embedNode
     * @return {Node} the embedNode
     */
    ResolveEmbed.prototype._setLoading = function (embedNode) {
        return embedNode.addClass('is-embed-loading');
    };

    /**
     * Appends the content node to the embed node.
     *
     * @method _appendContentNode
     * @private
     * @param {Node} embedNode
     * @return {Node} the content node
     */
    ResolveEmbed.prototype._appendContentNode = function (embedNode) {
        embedNode.append('<p class="ez-embed-content"></p>');
        return this._getEmbedContent(embedNode);
    };

    /**
     * Appends the embed content element when in loading mode.
     *
     * @method _appendLoadingNode
     * @protected
     * @param {Node} embedNode
     */
    ResolveEmbed.prototype._appendLoadingNode = function (embedNode) {
        this._appendContentNode(embedNode).setContent(Y.eZ.trans('loading...', {}, 'fieldedit'));
    };

    /**
     * Unsets the loading mode by remove the loading class.
     *
     * @method _unsetLoading
     * @protected
     * @param {Node} embedNode
     * @return {Node} embedNode
     */
    ResolveEmbed.prototype._unsetLoading = function (embedNode) {
        return embedNode.removeClass('is-embed-loading');
    };

    /**
     * Sets the embed node in the not loaded state
     *
     * @method _setNotLoaded
     * @protected
     * @param {Node} embedNode
     */
    ResolveEmbed.prototype._setNotLoaded = function (embedNode) {
        embedNode.addClass('is-embed-not-loaded');
        this._getEmbedContent(embedNode).setContent(this._notLoadedMessage);
    };

    /**
     * Returns the node representing the embed content.
     *
     * @method _getEmbedContent
     * @protected
     * @param {Node} embedNode
     * @return {Node}
     */
    ResolveEmbed.prototype._getEmbedContent = function (embedNode) {
        return embedNode.one('.ez-embed-content');
    };

    Y.eZ.RichTextResolveEmbed = ResolveEmbed;
});