UNPKG

snakeskin

Version:

Компилятор блочных шаблонов c поддержкой наследования.

166 lines (127 loc) 3.65 kB
/** * Вернуть полное тело заданного шаблона * при наследовании * * @param {string} tplName - название шаблона * @return {string} */ DirObj.prototype.getFullBody = function (tplName) { var protoLength = 'proto'.length, constLength = 1; var isDecl = []; forIn(this.getGroup('inherit'), (el, key) => { isDecl.push(key); }); var length = isDecl.length * 2, is = {}; for (let i = -1, j = 0; ++i < isDecl.length;) { is[i + j] = isDecl[i]; j++; is[i + j] = `${isDecl[i]}_add`; } var parentTpl = extMap[tplName], res = cache[parentTpl]; var alb = ADV_LEFT_BLOCK, lb = LEFT_BLOCK, rb = RIGHT_BLOCK; if (!this.tolerateWhitespace) { res += `${alb}${lb}__&-__${rb}`; } var from = 0, advDiff = []; var sornFn = (a, b) => a.val - b.val; var tb = table[tplName], k; var el, prev; var newFrom, blockDiff; for (let i = -1; ++i < length;) { let type = is[i]; if (routerCache[type]) { k = `${type}_`; el = routerCache[type][tplName]; prev = routerCache[type][parentTpl]; if (routerFromCache[type]) { from = routerFromCache[type][parentTpl]; newFrom = null; } } for (let key in el) { /* istanbul ignore if */ if (!el.hasOwnProperty(key)) { continue; } // Сдвиг относительно // родительской позиции элемента let adv = 0; let current = el[key], parent = !tb[k + key].drop && prev[key]; let block = cache[tplName] .substring(current.from, current.to); // Разница между дочерним и родительским блоком if (parent) { if (parent.output != null && current.output == null && (i % 2 === 0)) { current.output = parent.output; if (type === 'const') { block += current.output; } else { this.getBlockOutput(type, tplName)[key] = current.output; } } blockDiff = block.length - cache[parentTpl].substring(parent.from, parent.to).length; } let diff = parent ? parent.from : from; advDiff.sort(sornFn); for (let j = -1; ++j < advDiff.length;) { if (advDiff[j].val <= diff) { adv += advDiff[j].adv; } else { break; } } // Переопределение if (parent && (i % 2 === 0)) { if (type !== 'block' && (type !== 'const' || !current.block)) { newFrom = parent.from + adv + block.length; from += blockDiff; if (newFrom > from) { from = newFrom + (type === 'proto' ? protoLength : constLength); } } res = res.substring(0, parent.from + adv) + block + res.substring(parent.to + adv); advDiff.push({ val: parent.from, adv: blockDiff }); // Добавление } else if (!parent) { if (type === 'block_add') { res += block; } else if (type === 'const_add' || type === 'proto_add') { // Случай, если в дочернем шаблоне нет перекрытий, // но есть добавления нового if (newFrom === null) { newFrom = from; from += adv; } block = type === 'const_add' ? `${current.needPrfx ? alb : ''}${lb}${block}${rb}` : block; res = res.substring(0, from) + block + res.substring(from); advDiff.push({ val: newFrom, adv: block.length }); from = from + block.length; } } } } return res; };