| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>  <style type="text/css">    .highlight { display: block; background-color: #ddd; }  </style>  <script type="text/javascript">    function highlight() {      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";    }  </script></head><body onload="prettyPrint(); highlight();">  <pre class="prettyprint lang-js"><span id='Ext-XTemplateParser'>/**</span> * This class parses the XTemplate syntax and calls abstract methods to process the parts. * @private */Ext.define('Ext.XTemplateParser', {    constructor: function (config) {        Ext.apply(this, config);    },<span id='Ext-XTemplateParser-property-level'>    /**</span>     * @property {Number} level The 'for' loop context level. This is adjusted up by one     * prior to calling {@link #doFor} and down by one after calling the corresponding     * {@link #doEnd} that closes the loop. This will be 1 on the first {@link #doFor}     * call.     */<span id='Ext-XTemplateParser-method-doText'>    /**</span>     * This method is called to process a piece of raw text from the tpl.     * @param {String} text     * @method doText     */    // doText: function (text)<span id='Ext-XTemplateParser-method-doExpr'>    /**</span>     * This method is called to process expressions (like `{[expr]}`).     * @param {String} expr The body of the expression (inside "{[" and "]}").     * @method doExpr     */    // doExpr: function (expr)<span id='Ext-XTemplateParser-method-doTag'>    /**</span>     * This method is called to process simple tags (like `{tag}`).     * @method doTag     */    // doTag: function (tag)<span id='Ext-XTemplateParser-method-doElse'>    /**</span>     * This method is called to process `<tpl else>`.     * @method doElse     */    // doElse: function ()<span id='Ext-XTemplateParser-method-doEval'>    /**</span>     * This method is called to process `{% text %}`.     * @param {String} text     * @method doEval     */    // doEval: function (text)<span id='Ext-XTemplateParser-method-doIf'>    /**</span>     * This method is called to process `<tpl if="action">`. If there are other attributes,     * these are passed in the actions object.     * @param {String} action     * @param {Object} actions Other actions keyed by the attribute name (such as 'exec').     * @method doIf     */    // doIf: function (action, actions)<span id='Ext-XTemplateParser-method-doElseIf'>    /**</span>     * This method is called to process `<tpl elseif="action">`. If there are other attributes,     * these are passed in the actions object.     * @param {String} action     * @param {Object} actions Other actions keyed by the attribute name (such as 'exec').     * @method doElseIf     */    // doElseIf: function (action, actions)<span id='Ext-XTemplateParser-method-doSwitch'>    /**</span>     * This method is called to process `<tpl switch="action">`. If there are other attributes,     * these are passed in the actions object.     * @param {String} action     * @param {Object} actions Other actions keyed by the attribute name (such as 'exec').     * @method doSwitch     */    // doSwitch: function (action, actions)<span id='Ext-XTemplateParser-method-doCase'>    /**</span>     * This method is called to process `<tpl case="action">`. If there are other attributes,     * these are passed in the actions object.     * @param {String} action     * @param {Object} actions Other actions keyed by the attribute name (such as 'exec').     * @method doCase     */    // doCase: function (action, actions)<span id='Ext-XTemplateParser-method-doDefault'>    /**</span>     * This method is called to process `<tpl default>`.     * @method doDefault     */    // doDefault: function ()<span id='Ext-XTemplateParser-method-doEnd'>    /**</span>     * This method is called to process `</tpl>`. It is given the action type that started     * the tpl and the set of additional actions.     * @param {String} type The type of action that is being ended.     * @param {Object} actions The other actions keyed by the attribute name (such as 'exec').     * @method doEnd     */    // doEnd: function (type, actions) <span id='Ext-XTemplateParser-method-doFor'>    /**</span>     * This method is called to process `<tpl for="action">`. If there are other attributes,     * these are passed in the actions object.     * @param {String} action     * @param {Object} actions Other actions keyed by the attribute name (such as 'exec').     * @method doFor     */    // doFor: function (action, actions)<span id='Ext-XTemplateParser-method-doExec'>    /**</span>     * This method is called to process `<tpl exec="action">`. If there are other attributes,     * these are passed in the actions object.     * @param {String} action     * @param {Object} actions Other actions keyed by the attribute name.     * @method doExec     */    // doExec: function (action, actions)<span id='Ext-XTemplateParser-method-doTpl'>    /**</span>     * This method is called to process an empty `<tpl>`. This is unlikely to need to be     * implemented, so a default (do nothing) version is provided.     * @method     */    doTpl: Ext.emptyFn,    parse: function (str) {        var me = this,            len = str.length,            aliases = { elseif: 'elif' },            topRe = me.topRe,            actionsRe = me.actionsRe,            index, stack, s, m, t, prev, frame, subMatch, begin, end, actions,            prop;        me.level = 0;        me.stack = stack = [];        for (index = 0; index < len; index = end) {            topRe.lastIndex = index;            m = topRe.exec(str);            if (!m) {                me.doText(str.substring(index, len));                break;            }            begin = m.index;            end = topRe.lastIndex;            if (index < begin) {                me.doText(str.substring(index, begin));            }            if (m[1]) {                end = str.indexOf('%}', begin+2);                me.doEval(str.substring(begin+2, end));                end += 2;            } else if (m[2]) {                end = str.indexOf(']}', begin+2);                me.doExpr(str.substring(begin+2, end));                end += 2;            } else if (m[3]) { // if ('{' token)                me.doTag(m[3]);            } else if (m[4]) { // content of a <tpl xxxxxx xxx> tag                actions = null;                while ((subMatch = actionsRe.exec(m[4])) !== null) {                    s = subMatch[2] || subMatch[3];                    if (s) {                        s = Ext.String.htmlDecode(s); // decode attr value                        t = subMatch[1];                        t = aliases[t] || t;                        actions = actions || {};                        prev = actions[t];                        if (typeof prev == 'string') {                            actions[t] = [prev, s];                        } else if (prev) {                            actions[t].push(s);                        } else {                            actions[t] = s;                        }                    }                }                if (!actions) {                    if (me.elseRe.test(m[4])) {                        me.doElse();                    } else if (me.defaultRe.test(m[4])) {                        me.doDefault();                    } else {                        me.doTpl();                        stack.push({ type: 'tpl' });                    }                }                else if (actions['if']) {                    me.doIf(actions['if'], actions);                    stack.push({ type: 'if' });                }                else if (actions['switch']) {                    me.doSwitch(actions['switch'], actions);                    stack.push({ type: 'switch' });                }                else if (actions['case']) {                    me.doCase(actions['case'], actions);                }                else if (actions['elif']) {                    me.doElseIf(actions['elif'], actions);                }                else if (actions['for']) {                    ++me.level;                    // Extract property name to use from indexed item                    if (prop = me.propRe.exec(m[4])) {                        actions.propName = prop[1] || prop[2];                    }                    me.doFor(actions['for'], actions);                    stack.push({ type: 'for', actions: actions });                }                else if (actions.exec) {                    me.doExec(actions.exec, actions);                    stack.push({ type: 'exec', actions: actions });                }                /*                else {                    // todo - error                }                */            } else if (m[0].length === 5) {                // if the length of m[0] is 5, assume that we're dealing with an opening tpl tag with no attributes (e.g. <tpl>...</tpl>)                // in this case no action is needed other than pushing it on to the stack                stack.push({ type: 'tpl' });            } else {                frame = stack.pop();                me.doEnd(frame.type, frame.actions);                if (frame.type == 'for') {                    --me.level;                }            }        }    },    // Internal regexes        topRe:     /(?:(\{\%)|(\{\[)|\{([^{}]*)\})|(?:<tpl([^>]*)\>)|(?:<\/tpl>)/g,    actionsRe: /\s*(elif|elseif|if|for|exec|switch|case|eval)\s*\=\s*(?:(?:"([^"]*)")|(?:'([^']*)'))\s*/g,    propRe:    /prop=(?:(?:"([^"]*)")|(?:'([^']*)'))/,    defaultRe: /^\s*default\s*$/,    elseRe:    /^\s*else\s*$/});</pre></body></html>
 |