diff --git a/src/index.html b/src/index.html index b89817c..d46f663 100644 --- a/src/index.html +++ b/src/index.html @@ -60,6 +60,10 @@ fill: #dae9e5; } + .charset .charset-box { + fill: #cbcbba; + } + .placeholder text { fill: #fff; font-weight: bold; diff --git a/src/js/parser/javascript.js b/src/js/parser/javascript.js index 1ca0c4a..7679bb2 100644 --- a/src/js/parser/javascript.js +++ b/src/js/parser/javascript.js @@ -6,6 +6,9 @@ import Match from './javascript/match.js'; import MatchFragment from './javascript/match_fragment.js'; import Subexp from './javascript/subexp.js'; import Charset from './javascript/charset.js'; +import CharsetLiteral from './javascript/charset_literal.js'; +import CharsetEscape from './javascript/charset_escape.js'; +import CharsetRange from './javascript/charset_range.js'; import Literal from './javascript/literal.js'; import Escape from './javascript/escape.js'; import AnyCharacter from './javascript/any_character.js'; @@ -21,6 +24,9 @@ parser.Parser.Match = Match; parser.Parser.MatchFragment = MatchFragment; parser.Parser.Subexp = Subexp; parser.Parser.Charset = Charset; +parser.Parser.CharsetLiteral = CharsetLiteral; +parser.Parser.CharsetEscape = CharsetEscape; +parser.Parser.CharsetRange = CharsetRange; parser.Parser.Literal = Literal; parser.Parser.Escape = Escape; parser.Parser.AnyCharacter = AnyCharacter; diff --git a/src/js/parser/javascript/charset.js b/src/js/parser/javascript/charset.js index bafe595..b0661ff 100644 --- a/src/js/parser/javascript/charset.js +++ b/src/js/parser/javascript/charset.js @@ -2,5 +2,69 @@ import _ from 'lodash'; import Base from './base.js'; export default _.extend({}, Base, { - type: 'charset' + type: 'charset', + + render() { + this.container.addClass('charset'); + + this.label = this.container.text() + .attr({ + text: this.invert() ? 'None of:' : 'One of:' + }) + .transform(Snap.matrix() + .translate(0, 0)); + + this.box = this.container.rect() + .addClass('charset-box') + .attr({ + rx: 3, + ry: 3 + }); + + this.partContainer = this.container.group(); + + _.each(this.parts.elements, ((part) => { + part.container = this.partContainer.group(); + part.render(); + }).bind(this)); + }, + + position() { + var box, offset = 0; + + _.each(this.parts.elements, ((part) => { + var box; + + part.position(); + + part.container.transform(Snap.matrix() + .translate(0, offset)); + + box = part.container.getBBox(); + + offset += box.height + 5; + }).bind(this)); + + box = this.partContainer.getBBox(); + + _.each(this.parts.elements, ((part) => { + var partBox = part.container.getBBox(); + + part.container.transform(Snap.matrix() + .add(part.container.transform().localMatrix) + .translate(box.cx - partBox.cx, 0)); + }).bind(this)); + + this.box.attr({ + width: box.width + 10, + height: box.height + 10 + }); + + this.partContainer.transform(Snap.matrix() + .translate(5, 5)); + }, + + invert() { + return this._invert.textValue !== ''; + } }); diff --git a/src/js/parser/javascript/charset_escape.js b/src/js/parser/javascript/charset_escape.js new file mode 100644 index 0000000..331f678 --- /dev/null +++ b/src/js/parser/javascript/charset_escape.js @@ -0,0 +1,10 @@ +import _ from 'lodash'; +import Escape from './escape.js'; + +export default _.extend({}, Escape, { + type: 'charset_escape', + + codeMap: _.extend({}, Escape.codeMap, { + b: 'backspace' + }) +}); diff --git a/src/js/parser/javascript/charset_literal.js b/src/js/parser/javascript/charset_literal.js new file mode 100644 index 0000000..a418d1b --- /dev/null +++ b/src/js/parser/javascript/charset_literal.js @@ -0,0 +1,6 @@ +import _ from 'lodash'; +import Literal from './literal.js'; + +export default _.extend({}, Literal, { + type: 'literal' +}); diff --git a/src/js/parser/javascript/charset_range.js b/src/js/parser/javascript/charset_range.js new file mode 100644 index 0000000..160983c --- /dev/null +++ b/src/js/parser/javascript/charset_range.js @@ -0,0 +1,6 @@ +import _ from 'lodash'; +import Base from './base.js'; + +export default _.extend({}, Base, { + type: 'charset_range' +}); diff --git a/src/js/parser/javascript/grammar.peg b/src/js/parser/javascript/grammar.peg index 1646db6..490d844 100644 --- a/src/js/parser/javascript/grammar.peg +++ b/src/js/parser/javascript/grammar.peg @@ -20,15 +20,16 @@ grammar JavascriptRegexp subexp_no_capture <- "?:" subexp_positive_lookahead <- "?=" subexp_negative_lookahead <- "?!" - charset <- "[" "^"? ( charset_range / charset_terminal )* "]" - charset_range <- charset_terminal "-" charset_terminal - charset_terminal <- charset_escape / charset_literal + charset <- "[" _invert:"^"? parts:( charset_range / charset_terminal )* "]" + charset_range <- first:charset_terminal "-" last:charset_terminal + charset_terminal <- charset_escape + / charset_literal charset_escape <- "\\" esc:( code:[bdDfnrsStvwW] arg:""? / code:"0" arg:[0-7]+ / code:"x" arg:( [0-9a-fA-F] [0-9a-fA-F] ) / code:"u" arg:( [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] ) ) - charset_literal <- [^\\\]] / ( "\\" . ) + charset_literal <- ( ""? literal:[^\\\]] ) / ( "\\" literal:. ) terminal <- any_character / escape / literal diff --git a/src/js/parser/javascript/match_fragment.js b/src/js/parser/javascript/match_fragment.js index d1d01d9..0b19f3a 100644 --- a/src/js/parser/javascript/match_fragment.js +++ b/src/js/parser/javascript/match_fragment.js @@ -44,6 +44,6 @@ export default _.extend({}, Base, { .translate(0, 0)); } - this.render_bbox(this.container, this.container.getBBox()); + //this.render_bbox(this.container, this.container.getBBox()); } });