118 lines
2.8 KiB
JavaScript
118 lines
2.8 KiB
JavaScript
|
import parser from './parser/javascript.js';
|
||
|
import Snap from 'snapsvg';
|
||
|
import Q from 'q';
|
||
|
|
||
|
export default class Regexper {
|
||
|
constructor(root) {
|
||
|
this.root = root;
|
||
|
this.form = root.querySelector('#regexp-form');
|
||
|
this.field = root.querySelector('#regexp-input');
|
||
|
this.error = root.querySelector('#error');
|
||
|
this.permalink = root.querySelector('a[data-glyph="link-intact"]');
|
||
|
this.download = root.querySelector('a[data-glyph="data-transfer-download"]');
|
||
|
this.svg = root.querySelector('#regexp-render svg');
|
||
|
|
||
|
this.padding = 10;
|
||
|
this.snap = Snap(this.svg);
|
||
|
}
|
||
|
|
||
|
keypressListener(event) {
|
||
|
if (event.shiftKey && event.keyCode === 13) {
|
||
|
event.preventDefault();
|
||
|
this.form.dispatchEvent(new Event('submit'));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
submitListener(event) {
|
||
|
event.preventDefault();
|
||
|
|
||
|
location.hash = this.field.value;
|
||
|
}
|
||
|
|
||
|
hashchangeListener() {
|
||
|
var expression = decodeURIComponent(location.hash.slice(1)).replace(/[\r\n]/g, '');
|
||
|
|
||
|
if (expression !== '') {
|
||
|
this.field.value = expression;
|
||
|
|
||
|
this.setState('is-loading');
|
||
|
|
||
|
this.renderRegexp(expression)
|
||
|
.then((() => {
|
||
|
this.setState('has-results');
|
||
|
this.updateLinks();
|
||
|
}).bind(this), this.showError.bind(this));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bindListeners() {
|
||
|
this.field.addEventListener('keypress', this.keypressListener.bind(this));
|
||
|
|
||
|
this.form.addEventListener('submit', this.submitListener.bind(this));
|
||
|
|
||
|
window.addEventListener('hashchange', this.hashchangeListener.bind(this));
|
||
|
}
|
||
|
|
||
|
setState(state) {
|
||
|
var classList = this.root.classList;
|
||
|
|
||
|
classList.remove('is-loading', 'has-results', 'has-error');
|
||
|
classList.add(state);
|
||
|
}
|
||
|
|
||
|
showError(message) {
|
||
|
this.setState('has-error');
|
||
|
this.error.innerHTML = '';
|
||
|
this.error.appendChild(document.createTextNode(message));
|
||
|
}
|
||
|
|
||
|
updateLinks() {
|
||
|
var blob, url;
|
||
|
|
||
|
blob = new Blob([svg.outerHTML], { type: 'image/svg+xml' });
|
||
|
url = URL.createObjectURL(blob);
|
||
|
|
||
|
this.download.setAttribute('href', url);
|
||
|
this.permalink.setAttribute('href', location);
|
||
|
}
|
||
|
|
||
|
renderSvg(snap, expression) {
|
||
|
var result;
|
||
|
|
||
|
snap.selectAll('g').remove();
|
||
|
|
||
|
result = parser.parse(expression);
|
||
|
result.container = snap.group().transform(Snap.matrix()
|
||
|
.translate(this.padding, this.padding));
|
||
|
result.render();
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
positionSvg(snap, parsed) {
|
||
|
var box;
|
||
|
|
||
|
parsed.position();
|
||
|
|
||
|
box = parsed.container.getBBox();
|
||
|
snap.attr({
|
||
|
width: box.width + this.padding * 2,
|
||
|
height: box.height + this.padding * 2
|
||
|
});
|
||
|
}
|
||
|
|
||
|
renderRegexp(expression) {
|
||
|
var padding = this.padding,
|
||
|
snap = Snap(this.svg),
|
||
|
promise;
|
||
|
|
||
|
promise = Q.promise(((resolve, reject, notify) => {
|
||
|
resolve(this.renderSvg(snap, expression));
|
||
|
}).bind(this));
|
||
|
|
||
|
promise.then(this.positionSvg.bind(this, snap));
|
||
|
|
||
|
return promise;
|
||
|
}
|
||
|
}
|