hurt
Version:
HTTP and SPA routing using RFC 6570 URI templates
133 lines (105 loc) • 11.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.mixin = mixin;
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function mixin() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return {
attach: function attach() {
var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : options.window;
_attach(window, this, options);
return this;
}
};
}
function _attach(window, handler) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var history = window.history,
location = window.location,
document = window.document;
var base = (options.base ? canonicalizeUrl(options.base) : document.baseURI).replace(/\/$/, '');
var submit = null;
document.addEventListener('click', function (event) {
var target = event.target,
altKey = event.altKey,
metaKey = event.metaKey;
if (altKey || metaKey) {
return;
}
if (target.localName === 'button' && target.type === 'submit') {
submit = target;
}
if (target.localName === 'a' && target.href) {
run({ url: target.href, event: event });
}
});
document.addEventListener('submit', function (event) {
var target = event.target;
if (target.localName === 'form' && target.action) {
var url = canonicalizeUrl( /*submit.formAction ||*/target.action);
var method = submit.formMethod || target.method;
submit = null;
run({ url: url, method: method, event: event });
}
});
window.addEventListener('popstate', function (event) {
run({ url: location.href, replace: true, state: history.state, event: event });
});
function run(_ref) {
var url = _ref.url,
event = _ref.event,
options = _objectWithoutProperties(_ref, ['url', 'event']);
var req = {
method: (options.method || 'GET').toUpperCase(),
replace: options.replace || false,
state: options.state || {}
};
var res = emptyResponse();
if (url.substr(0, base.length) !== base) {
return false;
}
req.url = url.substr(base.length);
req.baseUrl = base;
if (event) {
event.stopPropagation();
event.preventDefault();
}
handler(req, res, function (err) {
if (err) {
return;
}
var method = req.replace ? history.replaceState : history.pushState;
var state = req.state;
method.call(history, state, state.title, base + req.url);
});
}
function canonicalizeUrl(href) {
var a = document.createElement('a');
a.href = href;
return a.href;
}
function emptyResponse() {
var handle = void 0;
var res = {
setTimeout: function setTimeout(timeout, callback) {
if (handle) {
clearTimeout(handle);
handle = null;
}
if (timeout) {
handle = window.setTimeout(callback, timeout);
}
},
end: function end() {
res.setTimeout(0);
res.finished = true;
},
finished: false
};
return res;
}
}
exports.attach = _attach;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kb20uanMiXSwibmFtZXMiOlsibWl4aW4iLCJvcHRpb25zIiwiYXR0YWNoIiwid2luZG93IiwiaGFuZGxlciIsImhpc3RvcnkiLCJsb2NhdGlvbiIsImRvY3VtZW50IiwiYmFzZSIsImNhbm9uaWNhbGl6ZVVybCIsImJhc2VVUkkiLCJyZXBsYWNlIiwic3VibWl0IiwiYWRkRXZlbnRMaXN0ZW5lciIsInRhcmdldCIsImV2ZW50IiwiYWx0S2V5IiwibWV0YUtleSIsImxvY2FsTmFtZSIsInR5cGUiLCJocmVmIiwicnVuIiwidXJsIiwiYWN0aW9uIiwibWV0aG9kIiwiZm9ybU1ldGhvZCIsInN0YXRlIiwicmVxIiwidG9VcHBlckNhc2UiLCJyZXMiLCJlbXB0eVJlc3BvbnNlIiwic3Vic3RyIiwibGVuZ3RoIiwiYmFzZVVybCIsInN0b3BQcm9wYWdhdGlvbiIsInByZXZlbnREZWZhdWx0IiwiZXJyIiwicmVwbGFjZVN0YXRlIiwicHVzaFN0YXRlIiwiY2FsbCIsInRpdGxlIiwiYSIsImNyZWF0ZUVsZW1lbnQiLCJoYW5kbGUiLCJzZXRUaW1lb3V0IiwidGltZW91dCIsImNhbGxiYWNrIiwiY2xlYXJUaW1lb3V0IiwiZW5kIiwiZmluaXNoZWQiXSwibWFwcGluZ3MiOiI7Ozs7O1FBQWdCQSxLLEdBQUFBLEs7Ozs7QUFBVCxTQUFTQSxLQUFULEdBQTZCO0FBQUEsTUFBZEMsT0FBYyx1RUFBSixFQUFJOzs7QUFFbEMsU0FBTztBQUNMQyxVQURLLG9CQUMyQjtBQUFBLFVBQXpCQyxNQUF5Qix1RUFBaEJGLFFBQVFFLE1BQVE7O0FBQzlCRCxjQUFPQyxNQUFQLEVBQWUsSUFBZixFQUFxQkYsT0FBckI7QUFDQSxhQUFPLElBQVA7QUFDRDtBQUpJLEdBQVA7QUFNRDs7QUFHTSxTQUFTQyxPQUFULENBQWdCQyxNQUFoQixFQUF3QkMsT0FBeEIsRUFBK0M7QUFBQSxNQUFkSCxPQUFjLHVFQUFKLEVBQUk7QUFBQSxNQUVsREksT0FGa0QsR0FLaERGLE1BTGdE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QUFjTixRQUFRZ0MsWUFBdEIsR0FBcUNoQyxRQUFRaUMsU0FBNUQ7QUFDQSxVQUFNWixRQUFRQyxJQUFJRCxLQUFsQjtBQUNBRixhQUFPZSxJQUFQLENBQVlsQyxPQUFaLEVBQXFCcUIsS0FBckIsRUFBNEJBLE1BQU1jLEtBQWxDLEVBQXlDaEMsT0FBT21CLElBQUlMLEdBQXBEO0FBQ0QsS0FSRDtBQVNEOztBQUVELFdBQVNiLGVBQVQsQ0FBeUJXLElBQXpCLEVBQStCO0FBQzdCLFFBQU1xQixJQUFJbEMsU0FBU21DLGFBQVQsQ0FBdUIsR0FBdkIsQ0FBVjtBQUNBRCxNQUFFckIsSUFBRixHQUFTQSxJQUFUO0FBQ0EsV0FBT3FCLEVBQUVyQixJQUFUO0FBQ0Q7O0FBRUQsV0FBU1UsYUFBVCxHQUF5QjtBQUN2QixRQUFJYSxlQUFKO0FBQ0EsUUFBTWQsTUFBTTtBQUNWZSxnQkFEVSxzQkFDQ0MsT0FERCxFQUNVQyxRQURWLEVBQ29CO0FBQzVCLFlBQUlILE1BQUosRUFBWTtBQUNWSSx1QkFBYUosTUFBYjtBQUNBQSxtQkFBUyxJQUFUO0FBQ0Q7QUFDRCxZQUFJRSxPQUFKLEVBQWE7QUFDWEYsbUJBQVN4QyxPQUFPeUMsVUFBUCxDQUFrQkUsUUFBbEIsRUFBNEJELE9BQTVCLENBQVQ7QUFDRDtBQUNGLE9BVFM7QUFVVkcsU0FWVSxpQkFVSjtBQUNKbkIsWUFBSWUsVUFBSixDQUFlLENBQWY7QUFDQWYsWUFBSW9CLFFBQUosR0FBZSxJQUFmO0FBQ0QsT0FiUzs7QUFjVkEsZ0JBQVU7QUFkQSxLQUFaO0FBZ0JBLFdBQU9wQixHQUFQO0FBQ0Q7QUFDRiIsImZpbGUiOiJkb20uanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gbWl4aW4ob3B0aW9ucyA9IHt9KSB7XG5cbiAgcmV0dXJuIHtcbiAgICBhdHRhY2god2luZG93ID0gb3B0aW9ucy53aW5kb3cpIHtcbiAgICAgIGF0dGFjaCh3aW5kb3csIHRoaXMsIG9wdGlvbnMpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICB9O1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBhdHRhY2god2luZG93LCBoYW5kbGVyLCBvcHRpb25zID0ge30pIHtcbiAgY29uc3Qge1xuICAgIGhpc3RvcnksXG4gICAgbG9jYXRpb24sXG4gICAgZG9jdW1lbnRcbiAgfSA9IHdpbmRvdztcblxuICBjb25zdCBiYXNlID0gKG9wdGlvbnMuYmFzZSA/IGNhbm9uaWNhbGl6ZVVybChvcHRpb25zLmJhc2UpIDogZG9jdW1lbnQuYmFzZVVSSSlcbiAgICAucmVwbGFjZSgvXFwvJC8sICcnKTtcblxuICBsZXQgc3VibWl0ID0gbnVsbDtcblxuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGV2ZW50ID0+IHtcbiAgICBjb25zdCB7IHRhcmdldCwgYWx0S2V5LCBtZXRhS2V5IH0gPSBldmVudDtcblxuICAgIGlmIChhbHRLZXkgfHwgbWV0YUtleSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0YXJnZXQubG9jYWxOYW1lID09PSAnYnV0dG9uJyAmJiB0YXJnZXQudHlwZSA9PT0gJ3N1Ym1pdCcpIHtcbiAgICAgIHN1Ym1pdCA9IHRhcmdldDtcbiAgICB9XG4gICAgaWYgKHRhcmdldC5sb2NhbE5hbWUgPT09ICdhJyAmJiB0YXJnZXQuaHJlZikge1xuICAgICAgcnVuKHsgdXJsOiB0YXJnZXQuaHJlZiwgZXZlbnQgfSk7XG4gICAgfVxuICB9KTtcblxuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdzdWJtaXQnLCBldmVudCA9PiB7XG4gICAgY29uc3QgeyB0YXJnZXQgfSA9IGV2ZW50O1xuXG4gICAgaWYgKHRhcmdldC5sb2NhbE5hbWUgPT09ICdmb3JtJyAmJiB0YXJnZXQuYWN0aW9uKSB7XG4gICAgICBjb25zdCB1cmwgPSBjYW5vbmljYWxpemVVcmwoLypzdWJtaXQuZm9ybUFjdGlvbiB8fCovIHRhcmdldC5hY3Rpb24pO1xuICAgICAgY29uc3QgbWV0aG9kID0gc3VibWl0LmZvcm1NZXRob2QgfHwgdGFyZ2V0Lm1ldGhvZDtcbiAgICAgIHN1Ym1pdCA9IG51bGw7XG4gICAgICBydW4oeyB1cmwsIG1ldGhvZCwgZXZlbnQgfSk7XG4gICAgfVxuICB9KTtcblxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBldmVudCA9PiB7XG4gICAgcnVuKHsgdXJsOiBsb2NhdGlvbi5ocmVmLCByZXBsYWNlOiB0cnVlLCBzdGF0ZTogaGlzdG9yeS5zdGF0ZSwgZXZlbnQgfSk7XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIHJ1bih7IHVybCwgZXZlbnQsIC4uLm9wdGlvbnMgfSkge1xuICAgIGNvbnN0IHJlcSA9IHtcbiAgICAgIG1ldGhvZDogKG9wdGlvbnMubWV0aG9kIHx8ICdHRVQnKS50b1VwcGVyQ2FzZSgpLFxuICAgICAgcmVwbGFjZTogb3B0aW9ucy5yZXBsYWNlIHx8IGZhbHNlLFxuICAgICAgc3RhdGU6IG9wdGlvbnMuc3RhdGUgfHwge31cbiAgICB9O1xuICAgIGNvbnN0IHJlcyA9IGVtcHR5UmVzcG9uc2UoKTtcblxuICAgIGlmICh1cmwuc3Vic3RyKDAsIGJhc2UubGVuZ3RoKSAhPT0gYmFzZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJlcS51cmwgPSB1cmwuc3Vic3RyKGJhc2UubGVuZ3RoKTtcbiAgICByZXEuYmFzZVVybCA9IGJhc2U7XG5cbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICBoYW5kbGVyKHJlcSwgcmVzLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWV0aG9kID0gcmVxLnJlcGxhY2UgPyBoaXN0b3J5LnJlcGxhY2VTdGF0ZSA6IGhpc3RvcnkucHVzaFN0YXRlO1xuICAgICAgY29uc3Qgc3RhdGUgPSByZXEuc3RhdGU7XG4gICAgICBtZXRob2QuY2FsbChoaXN0b3J5LCBzdGF0ZSwgc3RhdGUudGl0bGUsIGJhc2UgKyByZXEudXJsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbm9uaWNhbGl6ZVVybChocmVmKSB7XG4gICAgY29uc3QgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBhLmhyZWYgPSBocmVmO1xuICAgIHJldHVybiBhLmhyZWY7XG4gIH1cblxuICBmdW5jdGlvbiBlbXB0eVJlc3BvbnNlKCkge1xuICAgIGxldCBoYW5kbGU7XG4gICAgY29uc3QgcmVzID0ge1xuICAgICAgc2V0VGltZW91dCh0aW1lb3V0LCBjYWxsYmFjaykge1xuICAgICAgICBpZiAoaGFuZGxlKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KGhhbmRsZSk7XG4gICAgICAgICAgaGFuZGxlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGltZW91dCkge1xuICAgICAgICAgIGhhbmRsZSA9IHdpbmRvdy5zZXRUaW1lb3V0KGNhbGxiYWNrLCB0aW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVuZCgpIHtcbiAgICAgICAgcmVzLnNldFRpbWVvdXQoMCk7XG4gICAgICAgIHJlcy5maW5pc2hlZCA9IHRydWU7XG4gICAgICB9LFxuICAgICAgZmluaXNoZWQ6IGZhbHNlXG4gICAgfTtcbiAgICByZXR1cm4gcmVzO1xuICB9XG59XG4iXX0=