UNPKG

jii

Version:

Jii - Full-Stack JavaScript Framework

153 lines (127 loc) 4.85 kB
/** * @author <a href="http://www.affka.ru">Vladimir Kozhin</a> * @license MIT */ 'use strict'; const Jii = require('../BaseJii'); const _values = require('lodash/values'); const _each = require('lodash/each'); const WebView = require('./WebView'); class ServerWebView extends WebView { /** * * @param {*} view * @param {Context} context * @param {object} params * @param {Controller} controller * @returns {Promise} */ renderLayout(view, context, params, controller) { return super.renderLayout(view, context, params, controller).then(content => { content = content.replace(ServerWebView.PH_HEAD, this._renderHeadHtml()); content = content.replace(ServerWebView.PH_BODY_BEGIN, this._renderBodyBeginHtml()); content = content.replace(ServerWebView.PH_BODY_END, this._renderBodyEndHtml()); this.clear(); return Promise.resolve(content); }); } /** * Marks the position of an HTML head section. */ head() { return ServerWebView.PH_HEAD; } /** * Marks the beginning of an HTML body section. */ beginBody() { return ServerWebView.PH_BODY_BEGIN; } /** * Marks the ending of an HTML body section. */ endBody() { return ServerWebView.PH_BODY_END; } /** * Clears up the registered meta tags, link tags, css/js scripts and files. */ clear() { this.metaTags = {}; this.linkTags = {}; this.css = {}; this.cssFiles = {}; this.js = {}; this.jsFiles = {}; super.clear(); } /** * Renders the content to be inserted in the head section. * The content is rendered using the registered meta tags, link tags, CSS/JS code blocks and files. * @returns {string} the rendered content */ _renderHeadHtml() { return [].concat(_values(this.metaTags), _values(this.linkTags), _values(this.cssFiles), _values(this.css), _values(this.jsFiles[WebView.POS_HEAD]), _values(this.js[WebView.POS_HEAD])).join('\n'); } /** * Renders the content to be inserted at the beginning of the body section. * The content is rendered using the registered JS code blocks and files. * @returns {string} the rendered content */ _renderBodyBeginHtml() { return [].concat(_values(this.jsFiles[WebView.POS_BEGIN]), _values(this.js[WebView.POS_BEGIN])).join('\n'); } /** * Renders the content to be inserted at the end of the body section. * The content is rendered using the registered JS code blocks and files. * @returns {string} the rendered content */ _renderBodyEndHtml() { return [].concat(_values(this.jsFiles[WebView.POS_END]), _values(this.js[WebView.POS_END]), _values(this.js[WebView.POS_READY]), _values(this.js[WebView.POS_LOAD])).join('\n'); } _registerMetaTagInternal(key, options) { return '<meta' + this._renderTagAttributes(options) + ' />'; } _registerLinkTagInternal(key, options) { return '<link' + this._renderTagAttributes(options) + ' />'; } _registerCssInternal(key, code, options) { return '<style' + this._renderTagAttributes(options) + '>' + code + '</style>'; } _registerCssFileInternal(key, condition, noscript, options) { var html = '<link' + this._renderTagAttributes(options) + '>'; if (condition) { html = '<!--[if ' + condition + ']>\n' + html + '\n<![endif]-->'; } else if (noscript) { html = '<noscript>' + html + '</noscript>'; } return html; } _registerJsInternal(key, position, code, options) { switch (position) { case WebView.POS_READY: code = 'jQuery(document).ready(function () {\n' + code + '\n});'; break; case WebView.POS_LOAD: code = 'jQuery(window).load(function () {\n' + code + '\n});'; break; } return '<script type="text/javascript">' + code + '</script>'; } _registerJsFileInternal(key, position, condition, options) { var code = '<script' + this._renderTagAttributes(options) + '></script>'; if (condition) { code = '<!--[if ' + condition + ']>\n' + code + '\n<![endif]-->'; } return code; } _renderTagAttributes(options) { options = options || {}; var attributes = ''; _each(options, (value, key) => { attributes += ' ' + key + '="' + value + '"'; }); return attributes; } } module.exports = ServerWebView;