UNPKG

@progress/kendo-angular-common

Version:
742 lines (708 loc) 26.3 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2020 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { __decorate, __metadata, __extends } from 'tslib'; import { Input, Output, EventEmitter, Directive, ElementRef, NgZone, NgModule, Renderer2, Injectable, Component } from '@angular/core'; import Draggable from '@telerik/kendo-draggable'; import { CommonModule } from '@angular/common'; import { auditTime } from 'rxjs/operators'; import { merge, fromEvent, from } from 'rxjs'; var isDocumentAvailable = function () { return typeof document !== 'undefined'; }; var isChanged = function (propertyName, changes, skipFirstChange) { if (skipFirstChange === void 0) { skipFirstChange = true; } return (typeof changes[propertyName] !== 'undefined' && (!changes[propertyName].isFirstChange() || !skipFirstChange) && changes[propertyName].previousValue !== changes[propertyName].currentValue); }; var anyChanged = function (propertyNames, changes, skipFirstChange) { if (skipFirstChange === void 0) { skipFirstChange = true; } return propertyNames.some(function (name) { return isChanged(name, changes, skipFirstChange); }); }; var hasObservers = function (emitter) { return emitter && emitter.observers.length > 0; }; var guid = function () { var id = ""; for (var i = 0; i < 32; i++) { var random = Math.random() * 16 | 0; // tslint:disable-line:no-bitwise if (i === 8 || i === 12 || i === 16 || i === 20) { id += "-"; } // tslint:disable-next-line:no-bitwise id += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random)).toString(16); } return id; }; var DraggableDirective = /** @class */ (function () { function DraggableDirective(element, ngZone) { this.element = element; this.ngZone = ngZone; this.enableDrag = true; this.kendoPress = new EventEmitter(); this.kendoDrag = new EventEmitter(); this.kendoRelease = new EventEmitter(); } DraggableDirective.prototype.ngOnInit = function () { this.toggleDraggable(); }; DraggableDirective.prototype.ngOnChanges = function (changes) { if (isChanged('enableDrag', changes)) { this.toggleDraggable(); } }; DraggableDirective.prototype.ngOnDestroy = function () { this.destroyDraggable(); }; DraggableDirective.prototype.toggleDraggable = function () { var _this = this; if (isDocumentAvailable()) { this.destroyDraggable(); if (this.enableDrag) { this.draggable = new Draggable({ drag: function (e) { return _this.kendoDrag.next(e); }, press: function (e) { return _this.kendoPress.next(e); }, release: function (e) { return _this.kendoRelease.next(e); } }); this.ngZone.runOutsideAngular(function () { return _this.draggable.bindTo(_this.element.nativeElement); }); } } }; DraggableDirective.prototype.destroyDraggable = function () { if (this.draggable) { this.draggable.destroy(); this.draggable = null; } }; __decorate([ Input(), __metadata("design:type", Boolean) ], DraggableDirective.prototype, "enableDrag", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], DraggableDirective.prototype, "kendoPress", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], DraggableDirective.prototype, "kendoDrag", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], DraggableDirective.prototype, "kendoRelease", void 0); DraggableDirective = __decorate([ Directive({ selector: '[kendoDraggable]' }), __metadata("design:paramtypes", [ElementRef, NgZone]) ], DraggableDirective); return DraggableDirective; }()); /** * @hidden */ var DraggableModule = /** @class */ (function () { function DraggableModule() { } DraggableModule = __decorate([ NgModule({ declarations: [DraggableDirective], exports: [DraggableDirective], imports: [CommonModule] }) ], DraggableModule); return DraggableModule; }()); var closestInScope = function (node, predicate, scope) { while (node && node !== scope && !predicate(node)) { node = node.parentNode; } if (node !== scope) { return node; } }; var closest = function (node, predicate) { while (node && !predicate(node)) { node = node.parentNode; } return node; }; var contains = function (parent, node, matchSelf) { if (matchSelf === void 0) { matchSelf = false; } var outside = !closest(node, function (child) { return child === parent; }); if (outside) { return false; } var el = closest(node, function (child) { return child === node; }); return el && (matchSelf || el !== parent); }; var findElement = function (node, predicate, matchSelf) { if (matchSelf === void 0) { matchSelf = true; } if (!node) { return; } if (matchSelf && predicate(node)) { return node; } node = node.firstChild; while (node) { if (node.nodeType === 1) { var element = findElement(node, predicate); if (element) { return element; } } node = node.nextSibling; } }; var focusableRegex = /^(?:a|input|select|option|textarea|button|object)$/i; var isFocusable = function (element) { if (!element.tagName) { return false; } var tagName = element.tagName.toLowerCase(); var hasTabIndex = Boolean(element.getAttribute('tabIndex')); var focusable = !element.disabled && focusableRegex.test(tagName); return focusable || hasTabIndex; }; var isVisible = function (element) { var rect = element.getBoundingClientRect(); var hasSize = rect.width > 0 && rect.height > 0; var hasPosition = rect.x !== 0 && rect.y !== 0; // Elements can have zero size due to styling, but they will still count as visible. // For example, the selection checkbox has no size, but is made visible through styling. return (hasSize || hasPosition) && window.getComputedStyle(element).visibility !== 'hidden'; }; var isFocusableWithTabKey = function (element, checkVisibility) { if (checkVisibility === void 0) { checkVisibility = true; } if (!isFocusable(element)) { return false; } var tabIndex = element.getAttribute('tabIndex'); var visible = !checkVisibility || isVisible(element); return visible && tabIndex !== '-1'; }; var findFocusableChild = function (element, checkVisibility) { if (checkVisibility === void 0) { checkVisibility = true; } return findElement(element, function (node) { return isFocusableWithTabKey(node, checkVisibility); }, false); }; var findFocusable = function (element, checkVisibility) { if (checkVisibility === void 0) { checkVisibility = true; } return findElement(element, function (node) { return isFocusableWithTabKey(node, checkVisibility); }); }; var toClassList = function (classNames) { return String(classNames).trim().split(' '); }; var hasClasses = function (element, classNames) { var namesList = toClassList(classNames); return Boolean(toClassList(element.className).find(function (className) { return namesList.indexOf(className) >= 0; })); }; var matchesClasses = function (classNames) { return function (element) { return hasClasses(element, classNames); }; }; var NODE_NAME_PREDICATES = {}; var matchesNodeName = function (nodeName) { if (!NODE_NAME_PREDICATES[nodeName]) { NODE_NAME_PREDICATES[nodeName] = function (element) { return String(element.nodeName).toLowerCase() === nodeName.toLowerCase(); }; } return NODE_NAME_PREDICATES[nodeName]; }; /** * Normalizes a scroll position value in RTL mode. */ function rtlScrollPosition(position, element, initial) { var result = position; if (initial < 0) { result = -position; } else if (initial > 0) { result = element.scrollWidth - element.offsetWidth - position; } return result; } /* tslint:disable:no-input-rename */ /** * @hidden */ var EventsOutsideAngularDirective = /** @class */ (function () { function EventsOutsideAngularDirective(element, ngZone, renderer) { this.element = element; this.ngZone = ngZone; this.renderer = renderer; this.events = {}; } EventsOutsideAngularDirective.prototype.ngOnInit = function () { var _this = this; if (!this.element || !this.element.nativeElement) { return; } var events = this.events; this.subscriptions = []; this.ngZone.runOutsideAngular(function () { for (var name_1 in events) { if (events.hasOwnProperty(name_1)) { _this.subscriptions.push(_this.renderer.listen(_this.element.nativeElement, name_1, _this.scope ? events[name_1].bind(_this.scope) : events[name_1])); } } }); }; EventsOutsideAngularDirective.prototype.ngOnDestroy = function () { if (this.subscriptions) { for (var idx = 0; idx < this.subscriptions.length; idx++) { this.subscriptions[idx](); } this.subscriptions = null; } }; __decorate([ Input('kendoEventsOutsideAngular'), __metadata("design:type", Object) ], EventsOutsideAngularDirective.prototype, "events", void 0); __decorate([ Input(), __metadata("design:type", Object) ], EventsOutsideAngularDirective.prototype, "scope", void 0); EventsOutsideAngularDirective = __decorate([ Directive({ selector: '[kendoEventsOutsideAngular]' }), __metadata("design:paramtypes", [ElementRef, NgZone, Renderer2]) ], EventsOutsideAngularDirective); return EventsOutsideAngularDirective; }()); /** * @hidden */ var EventsModule = /** @class */ (function () { function EventsModule() { } EventsModule = __decorate([ NgModule({ declarations: [EventsOutsideAngularDirective], exports: [EventsOutsideAngularDirective] }) ], EventsModule); return EventsModule; }()); var ResizeService = /** @class */ (function () { function ResizeService(resizeBatchService) { this.resizeBatchService = resizeBatchService; this.resize = new EventEmitter(); this.acceptedSize = false; this.state = 0 /* Initial */; } ResizeService.prototype.acceptSize = function (size) { if (size === void 0) { size = this.measure(); } this.lastWidth = size.width; this.lastHeight = size.height; this.acceptedSize = true; }; ResizeService.prototype.checkChanges = function () { if (!isDocumentAvailable()) { return; } if (this.state === 0 /* Initial */) { this.state = 1 /* Initializing */; // batch initial measure this.resizeBatchService.schedule(this, this.init); } }; ResizeService.prototype.destroy = function () { this.resizeBatchService.cancel(this); }; ResizeService.prototype.checkSize = function () { if (!this.parentElement) { return; } var _a = this.measure(), width = _a.width, height = _a.height; var sameSize = width === this.lastWidth && height === this.lastHeight; if (sameSize) { return; } this.lastWidth = width; this.lastHeight = height; this.acceptedSize = false; this.resize.emit(); return true; }; ResizeService.prototype.initSize = function () { var size = this.measure(); this.lastWidth = size.width; this.lastHeight = size.height; }; ResizeService.prototype.measure = function () { var width = 0; var height = 0; if (this.parentElement) { height = this.parentElement.offsetHeight; width = this.parentElement.offsetWidth; } return { height: height, width: width }; }; return ResizeService; }()); // tslint:disable:deprecation var div = function (style) { var el = document.createElement('div'); el.style.cssText = style; return el; }; var computedProp = function (elem, prop) { return getComputedStyle(elem, null).getPropertyValue(prop); }; var WRAP_STYLE = 'position: absolute; display: block; left: 0; top: 0; right: 0; bottom: 0; z-index: -1;' + 'overflow: hidden; visibility: hidden;'; var EXPAND_CHILD_STYLE = 'position: absolute; left: 0; top: 0; transition: 0s;'; var SHRINK_CHILD_STYLE = EXPAND_CHILD_STYLE + 'width: 200%; height: 200%;'; var ResizeCompatService = /** @class */ (function (_super) { __extends(ResizeCompatService, _super); function ResizeCompatService(resizeBatchService, element, ngZone) { var _this = _super.call(this, resizeBatchService) || this; _this.element = element; _this.ngZone = ngZone; return _this; } ResizeCompatService.prototype.checkChanges = function () { if (this.state === 2 /* Initialized */) { if (!this.resizeBatchService.isScheduled(this)) { this.resizeBatchService.schedule(this, this.checkSize); } return; } _super.prototype.checkChanges.call(this); }; ResizeCompatService.prototype.destroy = function () { _super.prototype.destroy.call(this); if (this.subscription) { this.subscription.unsubscribe(); } if (this.expand) { var element = this.element.nativeElement; element.removeChild(this.expand); element.removeChild(this.shrink); this.expand.removeChild(this.expandChild); this.expand = this.expandChild = this.shrink = this.element = null; } }; ResizeCompatService.prototype.checkSize = function () { if (_super.prototype.checkSize.call(this)) { this.reset(); return true; } }; ResizeCompatService.prototype.init = function () { var parentElement = this.parentElement = this.element.nativeElement.parentElement; if (computedProp(parentElement, 'position') === 'static') { parentElement.style.position = 'relative'; } this.state = 2 /* Initialized */; this.render(); this.reset(); this.initSize(); this.subscribe(); }; ResizeCompatService.prototype.render = function () { var element = this.element.nativeElement; element.style.cssText = WRAP_STYLE; element.setAttribute('dir', 'ltr'); this.expand = div(WRAP_STYLE); this.expandChild = div(EXPAND_CHILD_STYLE); this.expand.appendChild(this.expandChild); element.appendChild(this.expand); this.shrink = div(WRAP_STYLE); var shrinkChild = div(SHRINK_CHILD_STYLE); this.shrink.appendChild(shrinkChild); element.appendChild(this.shrink); }; ResizeCompatService.prototype.reset = function () { var expandChild = this.expandChild; expandChild.style.width = 100000 + 'px'; expandChild.style.height = 100000 + 'px'; var expand = this.expand; expand.scrollLeft = 100000; expand.scrollTop = 100000; var shrink = this.shrink; shrink.scrollLeft = 100000; shrink.scrollTop = 100000; }; ResizeCompatService.prototype.subscribe = function () { var _this = this; this.ngZone.runOutsideAngular(function () { _this.subscription = merge(fromEvent(_this.shrink, 'scroll'), fromEvent(_this.expand, 'scroll')) .subscribe(function () { _this.checkSize(); }); }); }; return ResizeCompatService; }(ResizeService)); var HAS_OBSERVER = typeof ResizeObserver !== 'undefined'; /** * @hidden */ var ResizeObserverService = /** @class */ (function (_super) { __extends(ResizeObserverService, _super); function ResizeObserverService(resizeBatchService, element, ngZone) { var _this = _super.call(this, resizeBatchService) || this; _this.element = element; _this.ngZone = ngZone; return _this; } ResizeObserverService.supported = function () { return HAS_OBSERVER; }; ResizeObserverService.prototype.destroy = function () { _super.prototype.destroy.call(this); if (this.resizeObserver) { this.resizeObserver.disconnect(); this.resizeObserver = null; } this.parentElement = null; }; ResizeObserverService.prototype.init = function () { var _this = this; this.parentElement = this.element.nativeElement.parentElement; this.initSize(); this.state = 2 /* Initialized */; this.ngZone.runOutsideAngular(function () { _this.resizeObserver = new ResizeObserver(function () { _this.checkSize(); }); _this.resizeObserver.observe(_this.parentElement); }); }; return ResizeObserverService; }(ResizeService)); /* tslint:disable:align */ /** * @hidden */ var ResizeBatchService = /** @class */ (function () { function ResizeBatchService(ngZone) { this.ngZone = ngZone; this.scheduled = []; this.resolvedPromise = Promise.resolve(null); this.flush = this.flush.bind(this); } ResizeBatchService.prototype.schedule = function (instance, method) { var _this = this; this.scheduled.push({ instance: instance, method: method }); if (!this.subscription) { this.ngZone.runOutsideAngular(function () { _this.subscription = from(_this.resolvedPromise) .subscribe(_this.flush); }); } }; ResizeBatchService.prototype.isScheduled = function (instance) { return Boolean(this.scheduled.find(function (item) { return item.instance === instance; })); }; ResizeBatchService.prototype.cancel = function (instance) { var scheduled = this.scheduled; var count = scheduled.length; for (var idx = 0; idx < count; idx++) { if (scheduled[idx].instance === instance) { scheduled.splice(idx, 1); if (!scheduled.length) { this.unsubscribe(); } return; } } }; ResizeBatchService.prototype.ngOnDestroy = function () { this.unsubscribe(); }; ResizeBatchService.prototype.unsubscribe = function () { if (this.subscription) { this.subscription.unsubscribe(); this.subscription = null; } }; ResizeBatchService.prototype.flush = function () { this.scheduled.forEach(function (item) { item.method.call(item.instance); }); this.scheduled = []; this.unsubscribe(); }; ResizeBatchService = __decorate([ Injectable(), __metadata("design:paramtypes", [NgZone]) ], ResizeBatchService); return ResizeBatchService; }()); /** * Emit up to 10 resize events per second by default. * Chosen as a compromise between responsiveness and performance. */ var DEFAULT_RATE_LIMIT = 10; /** * Resize Sensor Component * * Triggers a "resize" event whenever the parent DOM element size changes. */ var ResizeSensorComponent = /** @class */ (function () { function ResizeSensorComponent(resizeBatchService, element, ngZone) { var _this = this; /** * The maximum number of resize events to emit per second. * * Defaults to 10. */ this.rateLimit = DEFAULT_RATE_LIMIT; /** * Fires when the parent DOM element has been resized. */ this.resize = new EventEmitter(); var serviceType = ResizeObserverService.supported() ? ResizeObserverService : ResizeCompatService; this.resizeService = new serviceType(resizeBatchService, element, ngZone); var throttleTime = 1000 / (this.rateLimit || DEFAULT_RATE_LIMIT); this.subscription = this.resizeService.resize .pipe(auditTime(throttleTime)) .subscribe(function () { if (!_this.resizeService.acceptedSize) { _this.resize.emit(); } }); } ResizeSensorComponent.prototype.ngAfterViewChecked = function () { this.resizeService.checkChanges(); }; ResizeSensorComponent.prototype.ngOnDestroy = function () { this.subscription.unsubscribe(); this.resizeService.destroy(); }; ResizeSensorComponent.prototype.acceptSize = function (size) { this.resizeService.acceptSize(size); }; __decorate([ Input(), __metadata("design:type", Number) ], ResizeSensorComponent.prototype, "rateLimit", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], ResizeSensorComponent.prototype, "resize", void 0); ResizeSensorComponent = __decorate([ Component({ selector: 'kendo-resize-sensor', template: '' }), __metadata("design:paramtypes", [ResizeBatchService, ElementRef, NgZone]) ], ResizeSensorComponent); return ResizeSensorComponent; }()); var COMPONENT_DIRECTIVES = [ResizeSensorComponent]; /** * Resize Sensor module */ var ResizeSensorModule = /** @class */ (function () { function ResizeSensorModule() { } ResizeSensorModule = __decorate([ NgModule({ declarations: [COMPONENT_DIRECTIVES], exports: [COMPONENT_DIRECTIVES], providers: [ResizeBatchService] }) ], ResizeSensorModule); return ResizeSensorModule; }()); var KendoInput = /** @class */ (function () { function KendoInput() { } return KendoInput; }()); /** * Enum with key codes. */ var Keys; (function (Keys) { Keys[Keys["Alt"] = 18] = "Alt"; Keys[Keys["ArrowDown"] = 40] = "ArrowDown"; Keys[Keys["ArrowLeft"] = 37] = "ArrowLeft"; Keys[Keys["ArrowRight"] = 39] = "ArrowRight"; Keys[Keys["ArrowUp"] = 38] = "ArrowUp"; Keys[Keys["Backspace"] = 8] = "Backspace"; Keys[Keys["Control"] = 17] = "Control"; Keys[Keys["Delete"] = 46] = "Delete"; Keys[Keys["Digit0"] = 48] = "Digit0"; Keys[Keys["Digit1"] = 49] = "Digit1"; Keys[Keys["Digit2"] = 50] = "Digit2"; Keys[Keys["Digit3"] = 51] = "Digit3"; Keys[Keys["Digit4"] = 52] = "Digit4"; Keys[Keys["Digit5"] = 53] = "Digit5"; Keys[Keys["Digit6"] = 54] = "Digit6"; Keys[Keys["Digit7"] = 55] = "Digit7"; Keys[Keys["Digit8"] = 56] = "Digit8"; Keys[Keys["Digit9"] = 57] = "Digit9"; Keys[Keys["End"] = 35] = "End"; Keys[Keys["Enter"] = 13] = "Enter"; Keys[Keys["Escape"] = 27] = "Escape"; Keys[Keys["F1"] = 112] = "F1"; Keys[Keys["F2"] = 113] = "F2"; Keys[Keys["F10"] = 121] = "F10"; Keys[Keys["Home"] = 36] = "Home"; Keys[Keys["Insert"] = 45] = "Insert"; Keys[Keys["KeyA"] = 65] = "KeyA"; Keys[Keys["KeyB"] = 66] = "KeyB"; Keys[Keys["KeyC"] = 67] = "KeyC"; Keys[Keys["KeyD"] = 68] = "KeyD"; Keys[Keys["KeyE"] = 69] = "KeyE"; Keys[Keys["KeyF"] = 70] = "KeyF"; Keys[Keys["KeyG"] = 71] = "KeyG"; Keys[Keys["KeyH"] = 72] = "KeyH"; Keys[Keys["KeyI"] = 73] = "KeyI"; Keys[Keys["KeyJ"] = 74] = "KeyJ"; Keys[Keys["KeyK"] = 75] = "KeyK"; Keys[Keys["KeyL"] = 76] = "KeyL"; Keys[Keys["KeyM"] = 77] = "KeyM"; Keys[Keys["KeyN"] = 78] = "KeyN"; Keys[Keys["KeyO"] = 79] = "KeyO"; Keys[Keys["KeyP"] = 80] = "KeyP"; Keys[Keys["KeyQ"] = 81] = "KeyQ"; Keys[Keys["KeyR"] = 82] = "KeyR"; Keys[Keys["KeyS"] = 83] = "KeyS"; Keys[Keys["KeyT"] = 84] = "KeyT"; Keys[Keys["KeyU"] = 85] = "KeyU"; Keys[Keys["KeyV"] = 86] = "KeyV"; Keys[Keys["KeyW"] = 87] = "KeyW"; Keys[Keys["KeyX"] = 88] = "KeyX"; Keys[Keys["KeyY"] = 89] = "KeyY"; Keys[Keys["KeyZ"] = 90] = "KeyZ"; Keys[Keys["NumpadDecimal"] = 110] = "NumpadDecimal"; Keys[Keys["PageDown"] = 34] = "PageDown"; Keys[Keys["PageUp"] = 33] = "PageUp"; Keys[Keys["Shift"] = 16] = "Shift"; Keys[Keys["Space"] = 32] = "Space"; Keys[Keys["Tab"] = 9] = "Tab"; })(Keys || (Keys = {})); var PreventableEvent = /** @class */ (function () { function PreventableEvent() { this.prevented = false; } /** * Prevents the default action for a specified event. * In this way, the source component suppresses * the built-in behavior that follows the event. */ PreventableEvent.prototype.preventDefault = function () { this.prevented = true; }; /** * Returns `true` if the event was prevented * by any of its subscribers. * * @returns `true` if the default action was prevented. * Otherwise, returns `false`. */ PreventableEvent.prototype.isDefaultPrevented = function () { return this.prevented; }; return PreventableEvent; }()); /** * Generated bundle index. Do not edit. */ export { ResizeService, PreventableEvent, DraggableDirective, DraggableModule, closestInScope, closest, contains, findElement, findFocusableChild, findFocusable, hasClasses, isFocusableWithTabKey, isFocusable, isVisible, matchesClasses, matchesNodeName, rtlScrollPosition, EventsOutsideAngularDirective, EventsModule, ResizeSensorComponent, ResizeBatchService, ResizeCompatService, ResizeObserverService, ResizeSensorModule, KendoInput, isDocumentAvailable, isChanged, anyChanged, hasObservers, guid, Keys };