Skip to content

Commit

Permalink
3.6.3
Browse files Browse the repository at this point in the history
  • Loading branch information
imaustink committed Nov 1, 2017
1 parent 5326c5e commit a0a48ea
Show file tree
Hide file tree
Showing 2 changed files with 1,013 additions and 0 deletions.
354 changes: 354 additions & 0 deletions dist/amd/can-view-parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,354 @@
/*can-view-parser@3.6.2#can-view-parser*/
define([
'require',
'exports',
'module',
'can-namespace',
'can-log/dev',
'can-attribute-encoder'
], function (require, exports, module) {
var namespace = require('can-namespace'), dev = require('can-log/dev'), encoder = require('can-attribute-encoder');
function each(items, callback) {
for (var i = 0; i < items.length; i++) {
callback(items[i], i);
}
}
function makeMap(str) {
var obj = {}, items = str.split(',');
each(items, function (name) {
obj[name] = true;
});
return obj;
}
function handleIntermediate(intermediate, handler) {
for (var i = 0, len = intermediate.length; i < len; i++) {
var item = intermediate[i];
handler[item.tokenType].apply(handler, item.args);
}
return intermediate;
}
var alphaNumeric = 'A-Za-z0-9', alphaNumericHU = '-:_' + alphaNumeric, defaultMagicStart = '{{', endTag = new RegExp('^<\\/([' + alphaNumericHU + ']+)[^>]*>'), defaultMagicMatch = new RegExp('\\{\\{(![\\s\\S]*?!|[\\s\\S]*?)\\}\\}\\}?', 'g'), space = /\s/, alphaRegex = new RegExp('[' + alphaNumeric + ']');
var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed');
var caseMattersElements = makeMap('altGlyph,altGlyphDef,altGlyphItem,animateColor,animateMotion,animateTransform,clipPath,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,foreignObject,glyphRef,linearGradient,radialGradient,textPath');
var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
var special = makeMap('script');
var tokenTypes = 'start,end,close,attrStart,attrEnd,attrValue,chars,comment,special,done'.split(',');
var startOppositesMap = {
'{': '}',
'(': ')'
};
var fn = function () {
};
var HTMLParser = function (html, handler, returnIntermediate) {
if (typeof html === 'object') {
return handleIntermediate(html, handler);
}
var intermediate = [];
handler = handler || {};
if (returnIntermediate) {
each(tokenTypes, function (name) {
var callback = handler[name] || fn;
handler[name] = function () {
if (callback.apply(this, arguments) !== false) {
var end = arguments.length;
if (arguments[end - 1] === undefined) {
end = arguments.length - 1;
}
intermediate.push({
tokenType: name,
args: [].slice.call(arguments, 0, end)
});
}
};
});
}
var magicMatch = handler.magicMatch || defaultMagicMatch, magicStart = handler.magicStart || defaultMagicStart;
function parseStartTag(tag, tagName, rest, unary) {
tagName = caseMattersElements[tagName] ? tagName : tagName.toLowerCase();
if (closeSelf[tagName] && stack.last() === tagName) {
parseEndTag('', tagName);
}
unary = empty[tagName] || !!unary;
handler.start(tagName, unary, lineNo);
if (!unary) {
stack.push(tagName);
}
HTMLParser.parseAttrs(rest, handler, lineNo);
handler.end(tagName, unary, lineNo);
}
function parseEndTag(tag, tagName) {
var pos;
if (!tagName) {
pos = 0;
} else {
tagName = caseMattersElements[tagName] ? tagName : tagName.toLowerCase();
for (pos = stack.length - 1; pos >= 0; pos--) {
if (stack[pos] === tagName) {
break;
}
}
}
if (pos >= 0) {
for (var i = stack.length - 1; i >= pos; i--) {
if (handler.close) {
handler.close(stack[i], lineNo);
}
}
stack.length = pos;
}
}
function parseMustache(mustache, inside) {
if (handler.special) {
handler.special(inside, lineNo);
}
}
var callChars = function () {
if (charsText) {
if (handler.chars) {
handler.chars(charsText, lineNo);
}
}
charsText = '';
};
var index, chars, match, lineNo, stack = [], last = html, charsText = '';
stack.last = function () {
return this[this.length - 1];
};
while (html) {
chars = true;
if (!stack.last() || !special[stack.last()]) {
if (html.indexOf('<!--') === 0) {
index = html.indexOf('-->');
if (index >= 0) {
callChars();
if (handler.comment) {
handler.comment(html.substring(4, index), lineNo);
}
html = html.substring(index + 3);
chars = false;
}
} else if (html.indexOf('</') === 0) {
match = html.match(endTag);
if (match) {
callChars();
match[0].replace(endTag, parseEndTag);
html = html.substring(match[0].length);
chars = false;
}
} else if (html.indexOf('<') === 0) {
var res = HTMLParser.searchStartTag(html);
if (res) {
callChars();
parseStartTag.apply(null, res.match);
html = res.html;
chars = false;
}
} else if (html.indexOf(magicStart) === 0) {
match = html.match(magicMatch);
if (match) {
callChars();
match[0].replace(magicMatch, parseMustache);
html = html.substring(match[0].length);
}
}
if (chars) {
index = findBreak(html, magicStart);
if (index === 0 && html === last) {
charsText += html.charAt(0);
html = html.substr(1);
index = findBreak(html, magicStart);
}
var text = index < 0 ? html : html.substring(0, index);
html = index < 0 ? '' : html.substring(index);
if (text) {
charsText += text;
}
}
} else {
html = html.replace(new RegExp('([\\s\\S]*?)</' + stack.last() + '[^>]*>'), function (all, text) {
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
if (handler.chars) {
handler.chars(text, lineNo);
}
return '';
});
parseEndTag('', stack.last());
}
if (html === last) {
throw new Error('Parse Error: ' + html);
}
last = html;
}
callChars();
parseEndTag();
handler.done(lineNo);
return intermediate;
};
var callAttrStart = function (state, curIndex, handler, rest, lineNo) {
var attrName = rest.substring(typeof state.nameStart === 'number' ? state.nameStart : curIndex, curIndex), newAttrName = encoder.encode(attrName);
state.attrStart = newAttrName;
handler.attrStart(state.attrStart, lineNo);
state.inName = false;
};
var callAttrEnd = function (state, curIndex, handler, rest, lineNo) {
if (state.valueStart !== undefined && state.valueStart < curIndex) {
var val = rest.substring(state.valueStart, curIndex);
handler.attrValue(val, lineNo);
}
handler.attrEnd(state.attrStart, lineNo);
state.attrStart = undefined;
state.valueStart = undefined;
state.inValue = false;
state.inName = false;
state.lookingForEq = false;
state.inQuote = false;
state.lookingForName = true;
};
var findBreak = function (str, magicStart) {
var magicLength = magicStart.length;
for (var i = 0, len = str.length; i < len; i++) {
if (str[i] === '<' || str.substr(i, magicLength) === magicStart) {
return i;
}
}
return -1;
};
HTMLParser.parseAttrs = function (rest, handler, lineNo) {
if (!rest) {
return;
}
var magicMatch = handler.magicMatch || defaultMagicMatch, magicStart = handler.magicStart || defaultMagicStart;
var i = 0;
var curIndex;
var state = {
inName: false,
nameStart: undefined,
inValue: false,
valueStart: undefined,
inQuote: false,
attrStart: undefined,
lookingForName: true,
lookingForValue: false,
lookingForEq: false
};
while (i < rest.length) {
curIndex = i;
var cur = rest.charAt(i);
i++;
if (magicStart === rest.substr(curIndex, magicStart.length)) {
if (state.inValue && curIndex > state.valueStart) {
handler.attrValue(rest.substring(state.valueStart, curIndex), lineNo);
} else if (state.inName && state.nameStart < curIndex) {
callAttrStart(state, curIndex, handler, rest, lineNo);
callAttrEnd(state, curIndex, handler, rest, lineNo);
} else if (state.lookingForValue) {
state.inValue = true;
} else if (state.lookingForEq && state.attrStart) {
callAttrEnd(state, curIndex, handler, rest, lineNo);
}
magicMatch.lastIndex = curIndex;
var match = magicMatch.exec(rest);
if (match) {
handler.special(match[1], lineNo);
i = curIndex + match[0].length;
if (state.inValue) {
state.valueStart = curIndex + match[0].length;
}
}
} else if (state.inValue) {
if (state.inQuote) {
if (cur === state.inQuote) {
callAttrEnd(state, curIndex, handler, rest, lineNo);
}
} else if (space.test(cur)) {
callAttrEnd(state, curIndex, handler, rest, lineNo);
}
} else if (cur === '=' && (state.lookingForEq || state.lookingForName || state.inName)) {
if (!state.attrStart) {
callAttrStart(state, curIndex, handler, rest, lineNo);
}
state.lookingForValue = true;
state.lookingForEq = false;
state.lookingForName = false;
} else if (state.inName) {
var started = rest[state.nameStart], otherStart, otherOpposite;
if (startOppositesMap[started] === cur) {
otherStart = started === '{' ? '(' : '{';
otherOpposite = startOppositesMap[otherStart];
if (rest[curIndex + 1] === otherOpposite) {
callAttrStart(state, curIndex + 2, handler, rest, lineNo);
i++;
} else {
callAttrStart(state, curIndex + 1, handler, rest, lineNo);
}
state.lookingForEq = true;
} else if (space.test(cur) && started !== '{' && started !== '(') {
callAttrStart(state, curIndex, handler, rest, lineNo);
state.lookingForEq = true;
}
} else if (state.lookingForName) {
if (!space.test(cur)) {
if (state.attrStart) {
callAttrEnd(state, curIndex, handler, rest, lineNo);
}
state.nameStart = curIndex;
state.inName = true;
}
} else if (state.lookingForValue) {
if (!space.test(cur)) {
state.lookingForValue = false;
state.inValue = true;
if (cur === '\'' || cur === '"') {
state.inQuote = cur;
state.valueStart = curIndex + 1;
} else {
state.valueStart = curIndex;
}
} else if (i === rest.length) {
callAttrEnd(state, curIndex, handler, rest, lineNo);
}
}
}
if (state.inName) {
callAttrStart(state, curIndex + 1, handler, rest, lineNo);
callAttrEnd(state, curIndex + 1, handler, rest, lineNo);
} else if (state.lookingForEq || state.lookingForValue || state.inValue) {
callAttrEnd(state, curIndex + 1, handler, rest, lineNo);
}
magicMatch.lastIndex = 0;
};
HTMLParser.searchStartTag = function (html) {
var closingIndex = html.indexOf('>');
if (closingIndex === -1 || !alphaRegex.test(html[1])) {
return null;
}
var tagName, tagContent, match, rest = '', unary = '';
var startTag = html.substring(0, closingIndex + 1);
var isUnary = startTag[startTag.length - 2] === '/';
var spaceIndex = startTag.search(space);
if (isUnary) {
unary = '/';
tagContent = startTag.substring(1, startTag.length - 2).trim();
} else {
tagContent = startTag.substring(1, startTag.length - 1).trim();
}
if (spaceIndex === -1) {
tagName = tagContent;
} else {
spaceIndex--;
tagName = tagContent.substring(0, spaceIndex);
rest = tagContent.substring(spaceIndex);
}
match = [
startTag,
tagName,
rest,
unary
];
return {
match: match,
html: html.substring(startTag.length)
};
};
module.exports = namespace.HTMLParser = HTMLParser;
});
Loading

0 comments on commit a0a48ea

Please sign in to comment.