nornj
Version:
A powerful template engine that can works with React, JSX enhancement or alternative tools.
189 lines (159 loc) • 4.51 kB
text/typescript
import nj from '../core';
import * as tools from '../utils/tools';
import { extensionConfig } from '../helpers/extension';
//提取xml open tag
export function getXmlOpenTag(obj, tmplRule) {
return tmplRule.xmlOpenTag.exec(obj);
}
//验证xml self close tag
const REGEX_XML_SELF_CLOSE_TAG = /^<[^>]+\/>$/i;
export function isXmlSelfCloseTag(obj) {
return REGEX_XML_SELF_CLOSE_TAG.test(obj);
}
//Verify self close tag name
export const OMITTED_CLOSE_TAGS = {
area: true,
base: true,
br: true,
col: true,
embed: true,
hr: true,
img: true,
input: true,
keygen: true,
link: true,
meta: true,
param: true,
source: true,
track: true,
wbr: true
};
export function verifySelfCloseTag(tagName) {
return OMITTED_CLOSE_TAGS[tagName.toLowerCase()];
}
//Extract parameters inside the xml open tag
export function getOpenTagParams(tag, tmplRule) {
const pattern = tmplRule.openTagParams;
let matchArr, ret;
while ((matchArr = pattern.exec(tag))) {
let key = matchArr[1];
if (key === '/') {
//If match to the last of "/", then continue the loop.
continue;
}
if (!ret) {
ret = [];
}
let value = matchArr[8],
onlyKey = false;
const onlyBrace = matchArr[4] != null ? matchArr[4] : matchArr[6];
if (value != null) {
value = tools.clearQuot(value); //Remove quotation marks
} else {
value = key; //Match to Similar to "checked" or "disabled" attribute.
if (!onlyBrace) {
onlyKey = true;
}
}
//Removed at the end of "/>", ">" or "/".
if (!matchArr[9] && !matchArr[10]) {
if (/\/>$/.test(value)) {
value = value.substr(0, value.length - 2);
} else if (/>$/.test(value) || /\/$/.test(value)) {
value = value.substr(0, value.length - 1);
}
}
//Transform special key
let hasColon;
if (key[0] === ':') {
key = key.substr(1);
hasColon = true;
}
ret.push({
key,
value,
onlyBrace,
hasColon,
onlyKey
});
}
return ret;
}
//判断xml close tag
export function isXmlCloseTag(obj, tagName) {
return tools.isString(obj) && obj.toLowerCase() === '</' + tagName + '>';
}
//get inside brace param
export function getInsideBraceParam(obj, tmplRule) {
return tmplRule.braceParam.exec(obj);
}
//判断扩展标签并返回参数
export function isEx(obj, tmplRule, noParams?) {
let ret;
const ret1 = tmplRule.extension.exec(obj);
if (ret1) {
ret = [ret1[1]];
if (!noParams) {
const params = getOpenTagParams(obj, tmplRule); //提取各参数
if (params) {
ret.push(params);
}
}
}
return ret;
}
export function isExAll(obj, tmplRule) {
return obj.match(tmplRule.exAll);
}
const REGEX_LOWER_CASE = /^[a-z]/;
const REGEX_UPPER_CASE = /^[A-Z]/;
export function fixExTagName(tagName, tmplRule) {
let ret;
if (!nj.fixTagName) {
return ret;
}
const _tagName = tools.lowerFirst(tagName),
config = extensionConfig[_tagName];
if (
config &&
(!config.needPrefix ||
(config.needPrefix == 'onlyUpperCase' && REGEX_LOWER_CASE.test(tagName)) ||
(config.needPrefix == 'onlyLowerCase' && REGEX_UPPER_CASE.test(tagName)))
) {
ret = tmplRule.extensionRule + _tagName;
}
return ret;
}
//Test whether as parameters extension
export function isParamsEx(name) {
return name === 'params' || name === 'props';
}
//Add to the "paramsEx" property of the parent node
export function addParamsEx(node, parent, isDirective, isSubTag) {
const exPropsName = 'paramsEx';
if (!parent[exPropsName]) {
let exPropsNode;
if (isDirective || isSubTag) {
exPropsNode = {
type: 'nj_ex',
ex: 'props',
content: [node]
};
} else {
exPropsNode = node;
}
exPropsNode.parentType = parent.type;
parent[exPropsName] = exPropsNode;
} else {
tools.arrayPush(parent[exPropsName].content, isDirective || isSubTag ? [node] : node.content);
}
}
export function exCompileConfig(name) {
return extensionConfig[name] || {};
}
export function isPropS(elemName, tmplRule) {
return elemName.indexOf(tmplRule.propRule) === 0;
}
export function isStrPropS(elemName, tmplRule) {
return elemName.indexOf(tmplRule.strPropRule + tmplRule.propRule) === 0;
}