UNPKG

6.38 kBJavaScriptView Raw
1/*!
2 * v-offline v2.2.0
3 * Offline and Online components for Vue
4 * (c) 2021 Vinayak Kulkarni<inbox.vinayak@gmail.com>
5 * Released under the MIT License
6 */
7
8import VueCompositionApi, { defineComponent, ref, computed, onBeforeUnmount } from '@vue/composition-api';
9import Ping from 'ping.js';
10
11var script = defineComponent({
12 name: 'VOffline',
13 props: {
14 onlineClass: {
15 type: String ,
16 required: false,
17 default: '',
18 },
19 offlineClass: {
20 type: String ,
21 required: false,
22 default: '',
23 },
24 pingUrl: {
25 type: String ,
26 required: false,
27 default: 'https://google.com',
28 },
29 },
30 setup(props, { emit }) {
31 // Local state
32 const isOnline = ref(navigator.onLine || false);
33 const events = ref(['online', 'offline', 'load']);
34 const url = ref(props.pingUrl || 'https://google.com');
35
36 // Local computed
37 const wrapperClass = computed(() => {
38 if (isOnline.value) {
39 return typeof props.onlineClass === 'string' ? props.onlineClass : '';
40 } else {
41 return typeof props.offlineClass === 'string'
42 ? props.offlineClass
43 : '';
44 }
45 });
46
47 /**
48 * Created lifecycle hook
49 */
50 events.value.forEach((event) => window.addEventListener(event, check));
51
52 /**
53 * Before unmount lifecycle hook
54 */
55 onBeforeUnmount(() => {
56 // Cleanup of the event listeners
57 events.value.forEach((event) =>
58 window.removeEventListener(event, check),
59 );
60 });
61
62 // Local functions
63 /**
64 * Pings the URL and emits an
65 * detected online/offline event.
66 *
67 * @returns {Promise<void>}
68 */
69 async function check() {
70 const p = new Ping();
71 try {
72 const ping = await p.ping(url.value);
73 if (ping || navigator.onLine) {
74 isOnline.value = true;
75 emit('detected-condition', isOnline.value);
76 }
77 } catch (error) {
78 if (error || !navigator.onLine) {
79 isOnline.value = false;
80 emit('detected-condition', isOnline.value);
81 }
82 }
83 }
84
85 return {
86 wrapperClass,
87 };
88 },
89});
90
91function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
92 if (typeof shadowMode !== 'boolean') {
93 createInjectorSSR = createInjector;
94 createInjector = shadowMode;
95 shadowMode = false;
96 }
97 // Vue.extend constructor export interop.
98 const options = typeof script === 'function' ? script.options : script;
99 // render functions
100 if (template && template.render) {
101 options.render = template.render;
102 options.staticRenderFns = template.staticRenderFns;
103 options._compiled = true;
104 // functional template
105 if (isFunctionalTemplate) {
106 options.functional = true;
107 }
108 }
109 // scopedId
110 if (scopeId) {
111 options._scopeId = scopeId;
112 }
113 let hook;
114 if (moduleIdentifier) {
115 // server build
116 hook = function (context) {
117 // 2.3 injection
118 context =
119 context || // cached call
120 (this.$vnode && this.$vnode.ssrContext) || // stateful
121 (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
122 // 2.2 with runInNewContext: true
123 if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
124 context = __VUE_SSR_CONTEXT__;
125 }
126 // inject component styles
127 if (style) {
128 style.call(this, createInjectorSSR(context));
129 }
130 // register component module identifier for async chunk inference
131 if (context && context._registeredComponents) {
132 context._registeredComponents.add(moduleIdentifier);
133 }
134 };
135 // used by ssr in case component is cached and beforeCreate
136 // never gets called
137 options._ssrRegister = hook;
138 }
139 else if (style) {
140 hook = shadowMode
141 ? function (context) {
142 style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
143 }
144 : function (context) {
145 style.call(this, createInjector(context));
146 };
147 }
148 if (hook) {
149 if (options.functional) {
150 // register for functional component in vue file
151 const originalRender = options.render;
152 options.render = function renderWithStyleInjection(h, context) {
153 hook.call(context);
154 return originalRender(h, context);
155 };
156 }
157 else {
158 // inject component registration as beforeCreate hook
159 const existing = options.beforeCreate;
160 options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
161 }
162 }
163 return script;
164}
165
166/* script */
167const __vue_script__ = script;
168
169/* template */
170var __vue_render__ = function () {
171 var _vm = this;
172 var _h = _vm.$createElement;
173 var _c = _vm._self._c || _h;
174 return _c("div", { class: _vm.wrapperClass }, [_vm._t("default")], 2)
175};
176var __vue_staticRenderFns__ = [];
177__vue_render__._withStripped = true;
178
179 /* style */
180 const __vue_inject_styles__ = undefined;
181 /* scoped */
182 const __vue_scope_id__ = undefined;
183 /* module identifier */
184 const __vue_module_identifier__ = undefined;
185 /* functional template */
186 const __vue_is_functional_template__ = false;
187 /* style inject */
188
189 /* style inject SSR */
190
191 /* style inject shadow dom */
192
193
194
195 const __vue_component__ = /*#__PURE__*/normalizeComponent(
196 { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
197 __vue_inject_styles__,
198 __vue_script__,
199 __vue_scope_id__,
200 __vue_is_functional_template__,
201 __vue_module_identifier__,
202 false,
203 undefined,
204 undefined,
205 undefined
206 );
207
208let installed = false;
209
210const install = {
211 install(Vue) {
212 if (installed) return;
213 Vue.use(VueCompositionApi);
214 Vue.component('VOffline', __vue_component__);
215 installed = true;
216 },
217};
218
219export default install;
220export { __vue_component__ as VOffline };
221//# sourceMappingURL=v-offline.esm.js.map