| 1 | /* |
| 2 | |
| 3 | MochiRegExp: JavaScript Regular Expression Explorer |
| 4 | |
| 5 | */ |
| 6 | RegExpManager = function () { |
| 7 | this.timer = null; |
| 8 | bindMethods(this); |
| 9 | }; |
| 10 | |
| 11 | RegExpManager.prototype.initialize = function () { |
| 12 | /* |
| 13 | Fill in the event handlers and sample text, and do the initial update |
| 14 | The reason we do the sample text here is so that "clear" really does |
| 15 | clear the fields. |
| 16 | */ |
| 17 | setNodeAttribute("inp_text", "value", "matched with your pattern"); |
| 18 | connect("inp_text", "onkeyup", this, "updateSoon"); |
| 19 | connect("inp_text", "onchange", this, "update"); |
| 20 | |
| 21 | setNodeAttribute("inp_regexp", "value", "/(pattern)/"); |
| 22 | connect("inp_regexp", "onkeyup", this, "updateSoon"); |
| 23 | connect("inp_regexp", "onchange", this, "update"); |
| 24 | |
| 25 | connect("regexp_form", "onsubmit", this, "submit"); |
| 26 | |
| 27 | this.update(); |
| 28 | }; |
| 29 | |
| 30 | RegExpManager.prototype.updateSoon = function () { |
| 31 | /* |
| 32 | If the user stops typing for half a second, do one update. |
| 33 | */ |
| 34 | this.cancelTimer(); |
| 35 | this.timer = callLater(0.5, this.update); |
| 36 | }; |
| 37 | |
| 38 | RegExpManager.prototype.cancelTimer = function () { |
| 39 | /* |
| 40 | Cancel the timer that waits for the user to idle for half a second. |
| 41 | */ |
| 42 | if (this.timer) { |
| 43 | this.timer.cancel(); |
| 44 | } |
| 45 | this.timer = null; |
| 46 | }; |
| 47 | |
| 48 | RegExpManager.prototype.update = function () { |
| 49 | /* |
| 50 | Cancel the update timer and actually do an update of the |
| 51 | RegExp |
| 52 | */ |
| 53 | this.cancelTimer(); |
| 54 | var re; |
| 55 | try { |
| 56 | // Evaluate the regexp |
| 57 | re = eval("(" + getElement("inp_regexp").value + ")"); |
| 58 | } catch (e) { |
| 59 | // If invalid, color it red and stop |
| 60 | addElementClass("lab_regexp", "error"); |
| 61 | return; |
| 62 | } |
| 63 | // Make sure that it's not red |
| 64 | removeElementClass("lab_regexp", "error"); |
| 65 | |
| 66 | // replace the contents of the tbody |
| 67 | var match = getElement("inp_text").value.match(re); |
| 68 | replaceChildNodes("result_body", this.getRows(match)); |
| 69 | }; |
| 70 | |
| 71 | RegExpManager.prototype.getRows = function (match) { |
| 72 | /* |
| 73 | Return rows for the tbody given a match object |
| 74 | */ |
| 75 | if (!match) { |
| 76 | // No match, bail with a no match row |
| 77 | return TR(null, TD({"colspan": "3"}, "No match!")); |
| 78 | } |
| 79 | var isAlternate = true; |
| 80 | var res = []; |
| 81 | for (var k in match) { |
| 82 | isAlternate = !isAlternate; |
| 83 | var trAttribs = isAlternate ? {"class": "alternate"} : null; |
| 84 | var v = match[k]; |
| 85 | var result = v; |
| 86 | // Highlight the result for the input property as three spans: |
| 87 | // [beforeMatch, duringMatch, afterMatch] |
| 88 | if (k == "input") { |
| 89 | var end = match.index + match[0].length; |
| 90 | result = [ |
| 91 | SPAN(null, v.substr(0, match.index)), |
| 92 | SPAN({"class": "highlight"}, v.substring(match.index, end)), |
| 93 | SPAN(null, v.substr(end)) |
| 94 | ]; |
| 95 | } |
| 96 | res.push( |
| 97 | TR((isAlternate ? {"class": "alternate"} : null), |
| 98 | TD(null, k), |
| 99 | TD(null, result), |
| 100 | TD(null, repr(v)) |
| 101 | ) |
| 102 | ); |
| 103 | } |
| 104 | return res; |
| 105 | }; |
| 106 | |
| 107 | RegExpManager.prototype.submit = function () { |
| 108 | this.update(); |
| 109 | return false; |
| 110 | }; |
| 111 | |
| 112 | regExpManager = new RegExpManager(); |
| 113 | addLoadEvent(regExpManager.initialize); |
| 114 | |
| 115 | // rewrite the view-source links |
| 116 | addLoadEvent(function () { |
| 117 | var elems = getElementsByTagAndClassName("A", "view-source"); |
| 118 | var page = "mochiregexp/"; |
| 119 | for (var i = 0; i < elems.length; i++) { |
| 120 | var elem = elems[i]; |
| 121 | var href = elem.href.split(/\//).pop(); |
| 122 | elem.target = "_blank"; |
| 123 | elem.href = "../view-source/view-source.html#" + page + href; |
| 124 | } |
| 125 | }); |