Skip to content

Commit

Permalink
自闭和标签校验,提供SELF_CLOSE表
Browse files Browse the repository at this point in the history
  • Loading branch information
army8735 committed May 14, 2015
1 parent 540d28e commit 5c1444e
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "homunculus",
"version": "0.9.3",
"version": "0.9.4",
"description": "A lexer&parser by Javascript",
"maintainers": [
{
Expand Down
31 changes: 31 additions & 0 deletions src/lexer/JSXLexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,25 @@ var JSXMatch = [
new RegMatch(JSXToken.PROPERTY, /^[a-z]+(?:-\w+)*/i)
];

var SELF_CLOSE = {
'img': true,
'meta': true,
'link': true,
'br': true,
'basefont': true,
'base': true,
'col': true,
'embed': true,
'frame': true,
'hr': true,
'input': true,
'keygen': true,
'area': true,
'param': true,
'source': true,
'track': true
};

var JSXLexer = Lexer.extend(function(rule) {
Lexer.call(this, rule);
}).methods({
Expand All @@ -31,6 +50,7 @@ var JSXLexer = Lexer.extend(function(rule) {
this.state = false; //是否在<>中
this.hStack = []; //当mark开始时++,减少时--,以此得知jsx部分结束回归js
this.jStack = []; //当{开始时++,减少时--,以此得知js部分结束回归jsx
this.selfClose = false; //当前jsx标签是否是自闭和
},
scan: function(temp) {
var perlReg = this.rule.perlReg();
Expand Down Expand Up @@ -66,6 +86,9 @@ var JSXLexer = Lexer.extend(function(rule) {
}
//>
else if(this.peek == '>') {
if(this.selfClose) {
this.error('self-close tag needs />');
}
this.state = false;
//>结束时,html深度若为0,说明html状态结束,或者栈最后一个计数器为0,也结束
if(!this.hStack.length || !this.hStack[this.hStack.length - 1]) {
Expand Down Expand Up @@ -257,6 +280,12 @@ var JSXLexer = Lexer.extend(function(rule) {
var token = new JSXToken(ELEM.tokenType(), ELEM.content(), ELEM.val(), this.index - 1);
var matchLen = ELEM.content().length;
this.dealToken(token, matchLen, 0, temp);
//自闭和没有.和:
if(SELF_CLOSE.hasOwnProperty(token.content().toLowerCase())) {
this.selfClose = true;
return;
}
this.selfClose = false;
var c = this.code.charAt(this.index);
if(c == '.') {
while(true) {
Expand Down Expand Up @@ -313,5 +342,7 @@ var JSXLexer = Lexer.extend(function(rule) {
}
}
}
}).statics({
SELF_CLOSE: SELF_CLOSE
});
module.exports = JSXLexer;
3 changes: 3 additions & 0 deletions src/parser/jsx/Parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var Es6Parser = require('../es6/Parser');
var Node = require('./Node');
var Token = require('../../lexer/JSXToken');
var character = require('../../util/character');
var Lexer = require('../../lexer/JSXLexer');

var Parser = Es6Parser.extend(function(lexer) {
Es6Parser.call(this, lexer);
Expand Down Expand Up @@ -234,6 +235,8 @@ var Parser = Es6Parser.extend(function(lexer) {
}
}
}
}).statics({
SELF_CLOSE: Lexer.SELF_CLOSE
});

module.exports = Parser;
6 changes: 6 additions & 0 deletions tests/jsxlexer2.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ describe('jsxlexer2', function() {
var tokens = lexer.parse('<a/>');
expect(join(tokens)).to.eql(['<', 'a', '/>']);
});
it('self close', function() {
var lexer = homunculus.getLexer('jsx');
expect(function() {
lexer.parse('<img>');
}).to.throwError();
});
it('with one attr', function() {
var lexer = homunculus.getLexer('jsx');
var tokens = lexer.parse('<a href="#"/>');
Expand Down
12 changes: 12 additions & 0 deletions tests/jsxparser2.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ describe('jsxparser2', function() {
var node = parser.parse('<a:b></a:b>');
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.EXPRSTMT,[JsNode.JSXElement,[JsNode.JSXOpeningElement,["<",JsNode.JSXMemberExpression,["a",":","b"],">"],JsNode.JSXClosingElement,["</",JsNode.JSXMemberExpression,["a",":","b"],">"]]]]]]);
});
it('self close', function() {
var parser = homunculus.getParser('jsx');
expect(function() {
parser.parse('<img>');
}).to.throwError();
});
it('mark missing', function() {
var parser = homunculus.getParser('jsx');
expect(function() {
parser.parse('<a>');
}).to.throwError();
});
it('mark mismatching', function() {
var parser = homunculus.getParser('jsx');
expect(function() {
Expand Down

0 comments on commit 5c1444e

Please sign in to comment.