UNPKG

@openhab-ui/setup-and-maintenance

Version:

Configuration and maintenance interface for openHAB

1,390 lines (1,178 loc) 36.7 kB
import '../vue.js'; var config = { itemsLimit: 1000 }; var ResizeObserver = { render: function render() { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c('div', { staticClass: "resize-observer", attrs: { "tabindex": "-1" } }); }, staticRenderFns: [], _scopeId: 'data-v-b329ee4c', name: 'resize-observer', methods: { compareAndNotify: function compareAndNotify() { if (this._w !== this.$el.offsetWidth || this._h !== this.$el.offsetHeight) { this._w = this.$el.offsetWidth; this._h = this.$el.offsetHeight; this.$emit('notify'); } }, addResizeHandlers: function addResizeHandlers() { this._resizeObject.contentDocument.defaultView.addEventListener('resize', this.compareAndNotify, { passive: true }); this.compareAndNotify(); }, removeResizeHandlers: function removeResizeHandlers() { if (this._resizeObject && this._resizeObject.onload) { if (this._resizeObject.contentDocument) { this._resizeObject.contentDocument.defaultView.removeEventListener('resize', this.compareAndNotify, { passive: true }); } delete this._resizeObject.onload; } } }, mounted: function mounted() { var _this = this; this.$nextTick(function () { _this._w = _this.$el.offsetWidth; _this._h = _this.$el.offsetHeight; }); var object = document.createElement('object'); this._resizeObject = object; object.setAttribute('aria-hidden', 'true'); object.setAttribute('tabindex', -1); object.onload = this.addResizeHandlers; object.type = 'text/html'; object.data = 'about:blank'; this.$el.appendChild(object); }, beforeDestroy: function beforeDestroy() { this.removeResizeHandlers(); } }; // Install the components function install(Vue$$1) { Vue$$1.component('resize-observer', ResizeObserver); Vue$$1.component('ResizeObserver', ResizeObserver); } // Plugin var plugin$2 = { // eslint-disable-next-line no-undef version: "0.4.5", install: install }; // Auto-install var GlobalVue$1 = null; if (typeof window !== 'undefined') { GlobalVue$1 = window.Vue; } else if (typeof global !== 'undefined') { GlobalVue$1 = global.Vue; } if (GlobalVue$1) { GlobalVue$1.use(plugin$2); } var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }; function processOptions(value) { var options = void 0; if (typeof value === 'function') { // Simple options (callback-only) options = { callback: value }; } else { // Options object options = value; } return options; } function throttle(callback, delay) { var timeout = void 0; var lastState = void 0; var currentArgs = void 0; var throttled = function throttled(state) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } currentArgs = args; if (timeout && state === lastState) return; lastState = state; clearTimeout(timeout); timeout = setTimeout(function () { callback.apply(undefined, [state].concat(toConsumableArray(currentArgs))); timeout = 0; }, delay); }; throttled._clear = function () { clearTimeout(timeout); }; return throttled; } function deepEqual(val1, val2) { if (val1 === val2) return true; if ((typeof val1 === 'undefined' ? 'undefined' : _typeof(val1)) === 'object') { for (var key in val1) { if (!deepEqual(val1[key], val2[key])) { return false; } } return true; } return false; } var VisibilityState = function () { function VisibilityState(el, options, vnode) { classCallCheck(this, VisibilityState); this.el = el; this.observer = null; this.frozen = false; this.createObserver(options, vnode); } createClass(VisibilityState, [{ key: 'createObserver', value: function createObserver(options, vnode) { var _this = this; if (this.observer) { this.destroyObserver(); } if (this.frozen) return; this.options = processOptions(options); this.callback = this.options.callback; // Throttle if (this.callback && this.options.throttle) { this.callback = throttle(this.callback, this.options.throttle); } this.oldResult = undefined; this.observer = new IntersectionObserver(function (entries) { var entry = entries[0]; if (_this.callback) { // Use isIntersecting if possible because browsers can report isIntersecting as true, but intersectionRatio as 0, when something very slowly enters the viewport. var result = entry.isIntersecting && entry.intersectionRatio >= _this.threshold; if (result === _this.oldResult) return; _this.oldResult = result; _this.callback(result, entry); if (result && _this.options.once) { _this.frozen = true; _this.destroyObserver(); } } }, this.options.intersection); // Wait for the element to be in document vnode.context.$nextTick(function () { _this.observer.observe(_this.el); }); } }, { key: 'destroyObserver', value: function destroyObserver() { if (this.observer) { this.observer.disconnect(); this.observer = null; } // Cancel throttled call if (this.callback && this.callback._clear) { this.callback._clear(); this.callback = null; } } }, { key: 'threshold', get: function get$$1() { return this.options.intersection && this.options.intersection.threshold || 0; } }]); return VisibilityState; }(); function bind(el, _ref, vnode) { var value = _ref.value; if (typeof IntersectionObserver === 'undefined') { console.warn('[vue-observe-visibility] IntersectionObserver API is not available in your browser. Please install this polyfill: https://github.com/w3c/IntersectionObserver/tree/master/polyfill'); } else { var state = new VisibilityState(el, value, vnode); el._vue_visibilityState = state; } } function update(el, _ref2, vnode) { var value = _ref2.value, oldValue = _ref2.oldValue; if (deepEqual(value, oldValue)) return; var state = el._vue_visibilityState; if (state) { state.createObserver(value, vnode); } else { bind(el, { value: value }, vnode); } } function unbind(el) { var state = el._vue_visibilityState; if (state) { state.destroyObserver(); delete el._vue_visibilityState; } } var ObserveVisibility = { bind: bind, update: update, unbind: unbind }; // Install the components function install$1(Vue$$1) { Vue$$1.directive('observe-visibility', ObserveVisibility); /* -- Add more components here -- */ } /* -- Plugin definition & Auto-install -- */ /* You shouldn't have to modify the code below */ // Plugin var plugin$4 = { // eslint-disable-next-line no-undef version: "0.4.3", install: install$1 }; // Auto-install var GlobalVue$2 = null; if (typeof window !== 'undefined') { GlobalVue$2 = window.Vue; } else if (typeof global !== 'undefined') { GlobalVue$2 = global.Vue; } if (GlobalVue$2) { GlobalVue$2.use(plugin$4); } var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var scrollparent = createCommonjsModule(function (module) { (function (root, factory) { if (module.exports) { module.exports = factory(); } else { root.Scrollparent = factory(); } }(commonjsGlobal, function () { var regex = /(auto|scroll)/; var parents = function (node, ps) { if (node.parentNode === null) { return ps; } return parents(node.parentNode, ps.concat([node])); }; var style = function (node, prop) { return getComputedStyle(node, null).getPropertyValue(prop); }; var overflow = function (node) { return style(node, "overflow") + style(node, "overflow-y") + style(node, "overflow-x"); }; var scroll = function (node) { return regex.test(overflow(node)); }; var scrollParent = function (node) { if (!(node instanceof HTMLElement || node instanceof SVGElement)) { return; } var ps = parents(node.parentNode, []); for (var i = 0; i < ps.length; i += 1) { if (scroll(ps[i])) { return ps[i]; } } return document.scrollingElement || document.documentElement; }; return scrollParent; })); }); if (typeof window !== 'undefined') { try { var opts = Object.defineProperty({}, 'passive', { get: function get() { } }); window.addEventListener('test', null, opts); } catch (e) { } } // @vue/component var Scroller = { components: { ResizeObserver: ResizeObserver }, directives: { ObserveVisibility: ObserveVisibility }, props: { items: { type: Array, required: true }, itemHeight: { type: Number, default: null }, minItemHeight: { type: [Number, String], default: null }, heightField: { type: String, default: 'height' }, typeField: { type: String, default: 'type' }, keyField: { type: String, default: 'id' }, buffer: { type: Number, default: 200 }, pageMode: { type: Boolean, default: false }, prerender: { type: Number, default: 0 }, emitUpdate: { type: Boolean, default: false } }, computed: { heights: function heights() { if (this.itemHeight === null) { var heights = { '-1': { accumulator: 0 } }; var items = this.items; var field = this.heightField; var minItemHeight = this.minItemHeight; var accumulator = 0; var current = void 0; for (var i = 0, l = items.length; i < l; i++) { current = items[i][field] || minItemHeight; accumulator += current; heights[i] = { accumulator: accumulator, height: current }; } return heights; } return []; } }, beforeDestroy: function beforeDestroy() { this.removeListeners(); }, methods: { getListenerTarget: function getListenerTarget() { var target = scrollparent(this.$el); // Fix global scroll target for Chrome and Safari if (target === window.document.documentElement || target === window.document.body) { target = window; } return target; }, getScroll: function getScroll() { var el = this.$el; // const wrapper = this.$refs.wrapper var scrollState = void 0; if (this.pageMode) { var size = el.getBoundingClientRect(); var top = -size.top; var height = window.innerHeight; if (top < 0) { height += top; top = 0; } if (top + height > size.height) { height = size.height - top; } scrollState = { top: top, bottom: top + height }; } else { scrollState = { top: el.scrollTop, bottom: el.scrollTop + el.clientHeight }; } return scrollState; }, applyPageMode: function applyPageMode() { if (this.pageMode) { this.addListeners(); } else { this.removeListeners(); } }, addListeners: function addListeners() { this.listenerTarget = this.getListenerTarget(); this.listenerTarget.addEventListener('scroll', this.handleScroll, { passive: true }); this.listenerTarget.addEventListener('resize', this.handleResize, { passive: true }); }, removeListeners: function removeListeners() { if (!this.listenerTarget) { return; } this.listenerTarget.removeEventListener('scroll', this.handleScroll, { passive: true }); this.listenerTarget.removeEventListener('resize', this.handleResize, { passive: true }); this.listenerTarget = null; }, scrollToItem: function scrollToItem(index) { var scrollTop = void 0; if (this.itemHeight === null) { scrollTop = index > 0 ? this.heights[index - 1].accumulator : 0; } else { scrollTop = index * this.itemHeight; } this.scrollToPosition(scrollTop); }, scrollToPosition: function scrollToPosition(position) { this.$el.scrollTop = position; }, itemsLimitError: function itemsLimitError() { var _this = this; setTimeout(function () { console.log('It seems the scroller element isn\'t scrolling, so it tries to render all the items at once.', 'Scroller:', _this.$el); console.log('Make sure the scroller has a fixed height and \'overflow-y\' set to \'auto\' so it can scroll correctly and only render the items visible in the scroll viewport.'); }); throw new Error('Rendered items limit reached'); } } }; var uid = 0; var RecycleScroller = { render: function render() { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c('div', { directives: [{ name: "observe-visibility", rawName: "v-observe-visibility", value: _vm.handleVisibilityChange, expression: "handleVisibilityChange" }], staticClass: "vue-recycle-scroller", class: { ready: _vm.ready, 'page-mode': _vm.pageMode }, on: { "&scroll": function scroll($event) { return _vm.handleScroll($event); } } }, [_vm._t("before-container"), _vm._v(" "), _c('div', { ref: "wrapper", staticClass: "vue-recycle-scroller__item-wrapper", style: { height: _vm.totalHeight + 'px' } }, _vm._l(_vm.pool, function (view) { return _c('div', { key: view.nr.id, staticClass: "vue-recycle-scroller__item-view", class: { hover: _vm.hoverKey === view.nr.key }, style: _vm.ready ? { transform: 'translateY(' + view.top + 'px)' } : null, on: { "mouseenter": function mouseenter($event) { _vm.hoverKey = view.nr.key; }, "mouseleave": function mouseleave($event) { _vm.hoverKey = null; } } }, [_vm._t("default", null, { item: view.item, index: view.nr.index, active: view.nr.used })], 2); }), 0), _vm._v(" "), _vm._t("after-container"), _vm._v(" "), _c('ResizeObserver', { on: { "notify": _vm.handleResize } })], 2); }, staticRenderFns: [], name: 'RecycleScroller', mixins: [Scroller], data: function data() { return { pool: [], totalHeight: 0, ready: false, hoverKey: null }; }, watch: { items: function items() { this.updateVisibleItems(true); }, pageMode: function pageMode() { this.applyPageMode(); this.updateVisibleItems(false); }, heights: { handler: function handler() { this.updateVisibleItems(false); }, deep: true } }, created: function created() { this.$_startIndex = 0; this.$_endIndex = 0; this.$_views = new Map(); this.$_unusedViews = new Map(); this.$_scrollDirty = false; if (this.$isServer) { this.updateVisibleItems(false); } }, mounted: function mounted() { var _this = this; this.applyPageMode(); this.$nextTick(function () { _this.updateVisibleItems(true); _this.ready = true; }); }, methods: { addView: function addView(pool, index, item, key, type) { var view = { item: item, top: 0 }; var nonReactive = { id: uid++, index: index, used: true, key: key, type: type }; Object.defineProperty(view, 'nr', { configurable: false, value: nonReactive }); pool.push(view); return view; }, unuseView: function unuseView(view) { var fake = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var unusedViews = this.$_unusedViews; var type = view.nr.type; var unusedPool = unusedViews.get(type); if (!unusedPool) { unusedPool = []; unusedViews.set(type, unusedPool); } unusedPool.push(view); if (!fake) { view.nr.used = false; view.top = -9999; this.$_views.delete(view.nr.key); } }, handleResize: function handleResize() { this.$emit('resize'); if (this.ready) this.updateVisibleItems(false); }, handleScroll: function handleScroll(event) { if (!this.$_scrollDirty) { this.$_scrollDirty = true; requestAnimationFrame(() => { this.$_scrollDirty = false; var _updateVisibleItems = this.updateVisibleItems(false), continuous = _updateVisibleItems.continuous; this.$emit('scrolled', this.$_startIndex, this.$_endIndex, this.items.length); // It seems sometimes chrome doesn't fire scroll event :/ // When non continous scrolling is ending, we force a refresh if (!continuous) { clearTimeout(this.$_refreshTimout); this.$_refreshTimout = setTimeout(this.handleScroll, 100); } }); } }, handleVisibilityChange: function handleVisibilityChange(isVisible, entry) { var _this3 = this; if (this.ready) { if (isVisible || entry.boundingClientRect.width !== 0 || entry.boundingClientRect.height !== 0) { this.$emit('visible'); requestAnimationFrame(function () { _this3.updateVisibleItems(false); }); } else { this.$emit('hidden'); } } }, updateVisibleItems: function updateVisibleItems(checkItem) { var itemHeight = this.itemHeight; var typeField = this.typeField; var keyField = this.keyField; var items = this.items; var count = items.length; var heights = this.heights; var views = this.$_views; var unusedViews = this.$_unusedViews; var pool = this.pool; var startIndex = void 0, endIndex = void 0; var totalHeight = void 0; if (!count) { startIndex = endIndex = totalHeight = 0; } else if (this.$isServer) { startIndex = 0; endIndex = this.prerender; totalHeight = null; } else { var scroll = this.getScroll(); var buffer = this.buffer; scroll.top -= buffer; scroll.bottom += buffer; // Variable height mode if (itemHeight === null) { var h = void 0; var a = 0; var b = count - 1; var i = ~~(count / 2); var oldI = void 0; // Searching for startIndex do { oldI = i; h = heights[i].accumulator; if (h < scroll.top) { a = i; } else if (i < count - 1 && heights[i + 1].accumulator > scroll.top) { b = i; } i = ~~((a + b) / 2); } while (i !== oldI); i < 0 && (i = 0); startIndex = i; // For container style totalHeight = heights[count - 1].accumulator; // Searching for endIndex for (endIndex = i; endIndex < count && heights[endIndex].accumulator < scroll.bottom; endIndex++) { } if (endIndex === -1) { endIndex = items.length - 1; } else { endIndex++; // Bounds endIndex > count && (endIndex = count); } } else { // Fixed height mode startIndex = ~~(scroll.top / itemHeight); endIndex = Math.ceil(scroll.bottom / itemHeight); // Bounds startIndex < 0 && (startIndex = 0); endIndex > count && (endIndex = count); totalHeight = count * itemHeight; } } if (endIndex - startIndex > config.itemsLimit) { this.itemsLimitError(); } this.totalHeight = totalHeight; var view = void 0; var continuous = startIndex <= this.$_endIndex && endIndex >= this.$_startIndex; var unusedIndex = void 0; if (this.$_continuous !== continuous) { if (continuous) { views.clear(); unusedViews.clear(); for (var _i = 0, l = pool.length; _i < l; _i++) { view = pool[_i]; this.unuseView(view); } } this.$_continuous = continuous; } else if (continuous) { for (var _i2 = 0, _l = pool.length; _i2 < _l; _i2++) { view = pool[_i2]; if (view.nr.used) { // Update view item index if (checkItem) { view.nr.index = items.findIndex(function (item) { return keyField ? item[keyField] === view.item[keyField] : item === view.item; }); } // Check if index is still in visible range if (view.nr.index === -1 || view.nr.index < startIndex || view.nr.index >= endIndex) { this.unuseView(view); } } } } if (!continuous) { unusedIndex = new Map(); } var item = void 0, type = void 0, unusedPool = void 0; var v = void 0; for (var _i3 = startIndex; _i3 < endIndex; _i3++) { item = items[_i3]; var key = keyField ? item[keyField] : item; view = views.get(key); if (!itemHeight && !heights[_i3].height) { if (view) this.unuseView(view); continue; } // No view assigned to item if (!view) { type = item[typeField]; if (continuous) { unusedPool = unusedViews.get(type); // Reuse existing view if (unusedPool && unusedPool.length) { view = unusedPool.pop(); view.item = item; view.nr.used = true; view.nr.index = _i3; view.nr.key = key; view.nr.type = type; } else { view = this.addView(pool, _i3, item, key, type); } } else { unusedPool = unusedViews.get(type); v = unusedIndex.get(type) || 0; // Use existing view // We don't care if they are already used // because we are not in continous scrolling if (unusedPool && v < unusedPool.length) { view = unusedPool[v]; view.item = item; view.nr.used = true; view.nr.index = _i3; view.nr.key = key; view.nr.type = type; unusedIndex.set(type, v + 1); } else { view = this.addView(pool, _i3, item, key, type); this.unuseView(view, true); } v++; } views.set(key, view); } else { view.nr.used = true; view.item = item; } // Update position if (itemHeight === null) { view.top = heights[_i3 - 1].accumulator; } else { view.top = _i3 * itemHeight; } } this.$_startIndex = startIndex; this.$_endIndex = endIndex; if (this.emitUpdate) this.$emit('update', startIndex, endIndex); return { continuous: continuous }; } } }; var DynamicScroller = { render: function render() { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c('RecycleScroller', _vm._g(_vm._b({ ref: "scroller", attrs: { "items": _vm.itemsWithHeight, "min-item-height": _vm.minItemHeight }, on: { "resize": _vm.onScrollerResize, "visible": _vm.onScrollerVisible }, scopedSlots: _vm._u([{ key: "default", fn: function fn(_ref) { var itemWithHeight = _ref.item, index = _ref.index, active = _ref.active; return [_vm._t("default", null, null, { item: itemWithHeight.item, index: index, active: active, itemWithHeight: itemWithHeight })]; } }]) }, 'RecycleScroller', _vm.$attrs, false), _vm.listeners), [_c('template', { slot: "before-container" }, [_vm._t("before-container")], 2), _vm._v(" "), _c('template', { slot: "after-container" }, [_vm._t("after-container")], 2)], 2); }, staticRenderFns: [], name: 'DynamicScroller', components: { RecycleScroller: RecycleScroller }, inheritAttrs: false, provide: function provide() { return { vscrollData: this.vscrollData, vscrollBus: this }; }, props: { items: { type: Array, required: true }, minItemHeight: { type: [Number, String], required: true }, keyField: { type: String, default: 'id' } }, data: function data() { return { vscrollData: { active: true, heights: {}, keyField: this.keyField } }; }, computed: { itemsWithHeight: function itemsWithHeight() { var result = []; var items = this.items; var keyField = this.keyField; var heights = this.vscrollData.heights; for (var i = 0; i < items.length; i++) { var item = items[i]; var id = item[keyField]; result.push({ item: item, id: id, height: heights[id] || 0 }); } return result; }, listeners: function listeners() { var listeners = {}; for (var key in this.$listeners) { if (key !== 'resize' && key !== 'visible') { listeners[key] = this.$listeners[key]; } } return listeners; } }, watch: { items: 'forceUpdate' }, created: function created() { this.$_updates = []; }, mounted: function mounted() { var scroller = this.$refs.scroller; var rect = this.getSize(scroller); this._scrollerWidth = rect.width; }, activated: function activated() { this.vscrollData.active = true; }, deactivated: function deactivated() { this.vscrollData.active = false; }, methods: { onScrollerResize: function onScrollerResize() { var scroller = this.$refs.scroller; if (scroller) { this.forceUpdate(); } this.$emit('resize'); }, onScrollerVisible: function onScrollerVisible() { this.$emit('vscroll:update', { force: false }); this.$emit('visible'); }, forceUpdate: function forceUpdate() { this.vscrollData.heights = {}; this.$emit('vscroll:update', { force: true }); }, getSize: function getSize(scroller) { return scroller.$el.getBoundingClientRect(); }, scrollToItem: function scrollToItem(index) { var scroller = this.$refs.scroller; if (scroller) scroller.scrollToItem(index); } } }; var DynamicScrollerItem = { name: 'DynamicScrollerItem', inject: ['vscrollData', 'vscrollBus'], props: { item: { type: Object, required: true }, watchData: { type: Boolean, default: false }, active: { type: Boolean, required: true }, sizeDependencies: { type: [Array, Object], default: null }, emitResize: { type: Boolean, default: false }, tag: { type: String, default: 'div' } }, computed: { id: function id() { return this.item[this.vscrollData.keyField]; }, height: function height() { return this.vscrollData.heights[this.id] || 0; } }, watch: { watchData: 'updateWatchData', id: function id() { if (!this.height) { this.onDataUpdate(); } }, active: function active(value) { if (value && this.$_pendingVScrollUpdate) { this.updateSize(); } } }, created: function created() { var _this = this; if (this.$isServer) return; this.$_forceNextVScrollUpdate = false; this.updateWatchData(); var _loop = function _loop(k) { _this.$watch(function () { return _this.sizeDependencies[k]; }, _this.onDataUpdate); }; for (var k in this.sizeDependencies) { _loop(k); } this.vscrollBus.$on('vscroll:update', this.onVscrollUpdate); this.vscrollBus.$on('vscroll:update-size', this.onVscrollUpdateSize); }, mounted: function mounted() { if (this.vscrollData.active) { this.updateSize(); } }, beforeDestroy: function beforeDestroy() { this.vscrollBus.$off('vscroll:update', this.onVscrollUpdate); this.vscrollBus.$off('vscroll:update-size', this.onVscrollUpdateSize); }, methods: { updateSize: function updateSize() { if (this.active && this.vscrollData.active) { if (!this.$_pendingSizeUpdate) { this.$_pendingSizeUpdate = true; this.$_forceNextVScrollUpdate = false; this.$_pendingVScrollUpdate = false; if (this.active && this.vscrollData.active) { this.computeSize(this.id); } } } else { this.$_forceNextVScrollUpdate = true; } }, getSize: function getSize() { return this.$el.getBoundingClientRect(); }, updateWatchData: function updateWatchData() { var _this2 = this; if (this.watchData) { this.$_watchData = this.$watch('data', function () { _this2.onDataUpdate(); }, { deep: true }); } else if (this.$_watchData) { this.$_watchData(); this.$_watchData = null; } }, onVscrollUpdate: function onVscrollUpdate(_ref) { var force = _ref.force; if (!this.active && force) { this.$_pendingVScrollUpdate = true; } if (this.$_forceNextVScrollUpdate || force || !this.height) { this.updateSize(); } }, onDataUpdate: function onDataUpdate() { this.updateSize(); }, computeSize: function computeSize(id) { var _this3 = this; this.$nextTick(function () { if (_this3.id === id) { var size = _this3.getSize(); if (size.height && _this3.height !== size.height) { _this3.$set(_this3.vscrollData.heights, _this3.id, size.height); if (_this3.emitResize) _this3.$emit('resize', _this3.id); } } _this3.$_pendingSizeUpdate = false; }); } }, render: function render(h) { return h(this.tag, this.$slots.default); } }; function registerComponents(Vue$$1, prefix) { Vue$$1.component(prefix + 'recycle-scroller', RecycleScroller); Vue$$1.component(prefix + 'RecycleScroller', RecycleScroller); Vue$$1.component(prefix + 'dynamic-scroller', DynamicScroller); Vue$$1.component(prefix + 'DynamicScroller', DynamicScroller); Vue$$1.component(prefix + 'dynamic-scroller-item', DynamicScrollerItem); Vue$$1.component(prefix + 'DynamicScrollerItem', DynamicScrollerItem); } var plugin = { // eslint-disable-next-line no-undef version: "1.0.0-beta.4", install: function install(Vue$$1, options) { var finalOptions = Object.assign({}, { installComponents: true, componentsPrefix: '' }, options); for (var key in finalOptions) { if (typeof finalOptions[key] !== 'undefined') { config[key] = finalOptions[key]; } } if (finalOptions.installComponents) { registerComponents(Vue$$1, finalOptions.componentsPrefix); } } }; // Auto-install var GlobalVue = null; if (typeof window !== 'undefined') { GlobalVue = window.Vue; } else if (typeof global !== 'undefined') { GlobalVue = global.Vue; } if (GlobalVue) { GlobalVue.use(plugin); } /** * Generate articial logs via https://next.json-generator.com. Pattern: [ { 'repeat(100)': { _id: '{{index()}}', timestamp: '{{date(new Date(2014, 0, 1), new Date()).getTime()}}', level: '{{random("INFO", "DEBUG", "WARN", "TRACE")}}', source: function (tags, parent) {return lorem(3, "word").replace(/ /g,".");} , message: '{{lorem(1, "sentences")}}', } } ] */ const Mixin = { mounted: function () { this.dateTimeFormat = new Intl.DateTimeFormat(navigator.language, { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' }); this.setFilter(""); }, data: function () { return { items: [], filtered: [], filterString: null } }, components: { 'dynamic-scroller': DynamicScroller, 'dynamic-scroller-item': DynamicScrollerItem }, methods: { setFilter(filterString) { if (!filterString || filterString == "") { this.filterString = null; this.filtered = this.items; return; } this.filterString = filterString; let newFilteredItems = []; for (let item of this.items) if (this.filterPass(item)) newFilteredItems.push(item); this.filtered = newFilteredItems; }, filterPass(item) { if (!this.filterString) return true; return item.message.match(this.filterString); }, newData(websocketData) { websocketData = websocketData.detail; if (!websocketData || websocketData.t !== "log") return; delete websocketData.t; if (websocketData.init) { let copy = []; for (let d of websocketData.init) { copy.push(d); } this.items = copy; this.setFilter(this.filterString); } else { this.addItem(websocketData); } }, addItem(item) { let copy = Object.assign({}, item); this.items.push(copy); if (this.filterString && this.filterPass(copy)) this.filtered.push(copy); if (this.items.length > 1000) { console.warn("Logbuffer too big. Pruning 800 items now"); this.items.splice(0, 800); if (this.filterString) this.setFilter(this.filterString); } // isScrollBottom is a boolean prop which is true if the user is scrolled at the bottom before the new message is added if (!this.$_scrollingToBottom && this.isScrollBottom) { this.$_scrollingToBottom = true; this.scrollToPosition(999999999); console.log("scroll"); } }, scrollDown(startIndex, endIndex, maxIndex) { this.isScrollBottom = endIndex == maxIndex; }, datetime(item) { return this.dateTimeFormat.format(new Date(item.timestamp)); }, loglevelClass(item) { switch (item.level) { case "TRACE": return "as-console-trace"; case "INFO": return "as-console-info"; case "DEBUG": return "as-console-debug"; case "INFO": return "as-console-warn"; case "ERROR": return "as-console-error"; } return "as-console-warn"; }, scrollToPosition(position) { const scroller = this.$refs.scroller.$el; scroller.scrollTop = position; requestAnimationFrame(() => { scroller.scrollTop = position; setTimeout(() => { scroller.scrollTop = position; this.$_scrollingToBottom = false; }, 50); }); }, } }; const mixins = [Mixin]; export { mixins };