UNPKG

5.28 kBJavaScriptView Raw
1import Vue from 'vue';
2
3var canNavigate = function (event) {
4 return (!event.defaultPrevented &&
5 (event.button !== undefined && event.button === 0) &&
6 !(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey));
7};
8var Link = {
9 name: "curi-link",
10 props: ["to", "params", "hash", "query", "state", "click"],
11 computed: {
12 location: function () {
13 var pathname = this.to
14 ? this.$router.route.pathname(this.to, this.params)
15 : this.$curi.response.location.pathname;
16 return {
17 hash: this.hash,
18 query: this.query,
19 state: this.state,
20 pathname: pathname
21 };
22 },
23 href: function () {
24 return this.$router.history.toHref(this.location);
25 }
26 },
27 data: function () {
28 return {
29 navigating: false
30 };
31 },
32 methods: {
33 clickHandler: function (event) {
34 var _this = this;
35 if (this.click) {
36 this.click(event);
37 }
38 if (canNavigate(event)) {
39 event.preventDefault();
40 var cancelled = void 0, finished = void 0;
41 if (this.$scopedSlots.default) {
42 cancelled = finished = function () {
43 _this.navigating = false;
44 };
45 this.navigating = true;
46 }
47 this.$router.navigate({
48 name: this.to,
49 params: this.params,
50 hash: this.hash,
51 query: this.query,
52 state: this.state,
53 cancelled: cancelled,
54 finished: finished
55 });
56 }
57 }
58 },
59 render: function (h) {
60 return h("a", {
61 attrs: { href: this.href },
62 on: { click: this.clickHandler }
63 }, this.$scopedSlots.default
64 ? this.$scopedSlots.default({
65 navigating: this.navigating
66 })
67 : this.$slots.default);
68 }
69};
70
71var Block = {
72 name: 'curi-block',
73 props: {
74 active: {
75 type: Boolean,
76 default: true
77 },
78 confirm: {
79 type: Function,
80 required: true
81 }
82 },
83 methods: {
84 on: function () {
85 this.$router.history.confirmWith(this.confirm);
86 },
87 off: function () {
88 this.$router.history.removeConfirmation();
89 },
90 update: function () {
91 this.off();
92 if (this.active) {
93 this.on();
94 }
95 }
96 },
97 beforeMount: function () {
98 if (this.active) {
99 this.on();
100 }
101 },
102 watch: {
103 active: function () {
104 this.update();
105 },
106 confirm: function () {
107 this.update();
108 }
109 },
110 beforeDestroy: function () {
111 this.off();
112 },
113 render: function (h) {
114 return null;
115 }
116};
117
118function focus(el, options) {
119 var _a = options.preserve, preserve = _a === void 0 ? false : _a, _b = options.preventScroll, preventScroll = _b === void 0 ? false : _b;
120 if (preserve && el.contains(document.activeElement)) {
121 return;
122 }
123 setTimeout(function () {
124 // @ts-ignore
125 el.focus({ preventScroll: preventScroll });
126 });
127}
128var focusDirection = {
129 inserted: function (el, binding) {
130 if (process.env.NODE_ENV !== "production") {
131 if (!el.hasAttribute("tabIndex") && el.tabIndex === -1) {
132 console.warn('The element that is passed the "v-curi-focus" directive must have a "tabIndex" prop or ' +
133 "be focusable by default in order to be focused. " +
134 "Otherwise, the document's <body> will be focused instead.");
135 }
136 }
137 focus(el, binding.value);
138 },
139 update: function (el, binding) {
140 if (binding.value.key !== binding.oldValue.key) {
141 focus(el, binding.value);
142 }
143 }
144};
145
146var CuriPlugin = {
147 install: function (_Vue, options) {
148 _Vue.component(Link.name, Link);
149 _Vue.component(Block.name, Block);
150 _Vue.directive("curi-focus", focusDirection);
151 // create a reactive object so that components will receive
152 // the new response/navigation when a new response is emitted
153 var reactive = new Vue({
154 data: { response: null, navigation: null }
155 });
156 options.router.observe(function (_a) {
157 var response = _a.response, navigation = _a.navigation;
158 reactive.response = response;
159 reactive.navigation = navigation;
160 });
161 _Vue.mixin({
162 beforeCreate: function () {
163 this.$curi = reactive;
164 }
165 });
166 Object.defineProperty(_Vue.prototype, "$router", {
167 get: function () {
168 return options.router;
169 }
170 });
171 }
172};
173
174export { CuriPlugin };